Post

[CS] Chapter 03. 명령어

혼자 공부하는 컴퓨터 구조 + 운영체제 (한빛미디어 출판, 강민철 지음) 으로 공부한 내용을 정리합니다.
CS Study를 통해 함께 공부하고 있습니다. [github repository]

✅ 03 - 1. 소스 코드와 명령어

소스 코드가 컴퓨터 내부에서 명령어가 되고 실행되는 과정 학습
핵심 키워드 : 고급 언어 저급 언어 기계어 어셈블리어 컴파일 언어 인터프리터 언어

✔️ 고급 언어와 저급 언어

고급 언어 (high-level programming language)
사람을 위한 언어. 우리가 알고 있는 대부분의 프로그래밍 언어.
저급 언어 (low-level programming language)
컴퓨터가 직접 이해하고 실행할 수 있는 언어. 명령어로 이루어져 있다.

저급 언어에는 기계어어셈블리어 두 가지 종류가 있다.

🔎 기계어 (machine code)
기계어(machine code)란 0과 1의 명령어 비트로 이루어진 언어. 이는 오로지 컴퓨터만을 위해 만들어진 언어이기에 사람이 읽으면 의미를 이해하기 어렵다.
🔎 어셈블리어 (assembly language)
기계어를 읽기 편한 형태로 번역한 저급 언어.
기계어어셈블리어
0101 0101push rbp
0101 1101pop rbp
1100 0011ret

하드웨어와 밀접하게 맞닿아 있는 프로그램을 개발하는 임베디드 개발자, 게임 개발자, 정보 보안 분야 등의 개발자는 어셈블리어를 많이 이용한다.

✔️ 컴파일 언어와 인터프리터 언어

컴파일 방식과 인터프리터 방식으로 고급 언어로 작성된 소스코드를 저급 언어로 변환한다.

🔎 컴파일 언어

컴파일 언어는 컴파일러에 의해 소스 코드 전체가 저급 언어로 변환되어 실행되는 고급 언어이다. 대표적인 언어로 C가 있다.

컴파일 언어로 작성된 소스 코드 전체가 저급 언어로 변환되는 과정을 컴파일(compile)이라고 한다. 이 컴파일을 수행해 주는 도구를 컴파일러(compiler)라고 한다. 이렇게 변화된 코드를 목적 코드(object code)라고 한다.

🔎 인터프리터 언어

인터프리터 언어는 인터프리터에 의해 소스 코드가 한 줄씩 실행되는 고급 언어이다. 대표적인 언어로 Python이 있다.

소스 코드 내에 오류가 하나라도 있으면 컴파일이 불가능한 컴파일 언어와 달리, 인터프리터 언어는 N 번째 줄에 오류가 있더라도, N-1 번째 줄 까지는 수행된다.

일반적으로 인터프리터 언어가 컴파일 언어보다 느리다. 목적 코드는 컴퓨터가 이해하고 실행할 수 있는 저급 언어인 반면, 인터프리터 언어는 소스 코드 마지막에 이를 때까지 한 줄 한 줄씩 저급 언어로 해석하며 실행해야 하기 때문

❓ 목적 파일 vs 실행 파일

목적 파일과 실행 파일(대표적으로 윈도우의 .exe 파일)은 다르다.

목적 코드가 실행 파일이 되기 위해서는 링킹이라는 작업을 거쳐야 한다.

✅ 03 - 2. 명령어의 구조

명령어의 구조와 구조 지정 방식을 학습하며 명령어의 생김새와 작동 원리를 이해
핵심 키워드 : 명령어 연산 코드 오퍼랜드 주소 지정 방식

✔️ 연산 코드와 오퍼랜드

명령어는 연산 코드오퍼랜드로 구성되어 있다.

🔎 오퍼랜드 (operand)

연산에 사용할 데이터가 저장된 위치. 피연산자라고도 부른다.

오퍼랜드가 담기는 영역을 오퍼랜드 필드라고 한다. 오퍼랜드 필드에는 메모리 주소나 레지스터 이름이 담긴다. 그래서 오퍼랜드 필드를 주소 필드라고 부르기도 한다.

0-주소 명령어
오퍼랜드가 하나도 없는 명령어
1-주소 명령어
오퍼랜드가 한 개인 명령어
2-주소 명령어
오퍼랜드가 두 개인 명령어
3-주소 명령어
오퍼랜드가 세 개인 명령어

🔎 연산 코드 (operation code)

명령어가 수행할 연산. 연산자라고도 부른다.

가장 기본적인 연산 코드 유형은 크게 네 가지이다.

  1. 데이터 전송
  2. 산술/논리 연산
  3. 제어 흐름 변경
  4. 입출력 제어
데이터 전송
  • MOVE : 데이터를 옮겨라
  • STORE : 메모리에 저장하라
  • LOAD(FETCH) : 메모리에서 CPU로 데이터를 가져와라
  • PUSH : 스택에 데이터를 저장하라
  • POP : 스택의 최상단 데이터를 가져와라
산술/논리 연산
  • ADD / SUBTRACT / MULTIPLY / DIVIDE : 덧셈 / 뺄셈 / 곱셈 / 나눗셈을 수행하라
  • INCREMENT / DECREMENT : 오퍼랜드에 1을 더하라 / 1을 빼라
  • AND / OR / NOT : AND / OR / NOT 연산을 수행하라
  • COMPARE : 두 개의 숫자 또는 TRUE / FALSE 값을 비교하라

제어 흐름 변경 :

  • JUMP : 특정 주소로 실행 순서를 옮겨라
  • CONDITIONAL JUMP : 조건에 부합할 때 특정 주소로 실행 순서를 옮겨라
  • HALT : 프로그램의 실행을 멈춰라
  • CALL : 되돌아올 주소를 저장한 채 특정 주소로 실행 순서를 옮겨라
  • RETURN : CALL을 호출할 때 저장했던 주소로 돌아가라

입출력 제어 :

  • READ(INPUT) : 특정 입출력 장치로부터 데이터를 읽어라
  • WRITE(OUTPUT) : 특정 입출력 장치로 데이터를 써라
  • START IO : 입출력 장치를 시작하라
  • TEST IO : 입출력 장치의 상태를 확인하라

✔️ 주소 지정 방식

주소 지정 방식(ADDRESSING MODE)은 오퍼랜드 필드에 데이터가 저장된 위치를 명시할 때 연산에 사용할 데이터 위치를 찾는 방법. 즉, 유효 주소를 찾는 방법이다.

❓ 오퍼랜드 필드에 데이터를 직접 넣지 않는 이유
메모리 주소를 명시함으로써 표현할 수 있는 정보의 가짓수를 늘린다.

🔎 즉시 주소 지정 방식

즉시 주소 지정 방식(immediate addressing mode)은 연산에 사용할 데이터를 오퍼랜드 필드에 직접 명시하는 방식. 표현할 수 있는 데이터의 크기가 작아지는 단점이 있지만, 연산에 사용할 데이터를 메모리나 레지스터로부터 찾는 과정이 없기 때문에 다른 주소 지정 방식들 보다 빠르다.

🔎 직접 주소 지정 방식

직접 주소 지정 방식(direct addressing mode)은 오퍼랜드 필드에 유효 주소를 직접적으로 명시하는 방식. 표현할 수 있는 데이터의 크기는 즉지 주소 지정 방식 보다 더 커졌지만, 유효 주소를 표현할 수 있는 범위가 연산 코드의 비트 수 만큼 줄어들었다.(표현할 수 있는 유효 주소에 제한이 생길 수 있다.)

🔎 간접 주소 지정 방식

간접 주소 지정 방식(indirect addressing mode)은 유효 주소의 주소를 오퍼랜드 필드에 명시한다. 직접 주소 지정 방식 보다 유효 주소의 범위가 더 넓어졌지만, 두 번의 메모리 접근이 필요하기 때문에 일반적으로 느린 방식이다.

🔎 레지스터 주소 지정 방식

레지스터 주소 지정 방식(register addressing mode)은 직접 주소 지정 방식과 비슷하게 연산에 사용할 데이터를 저장한 레지스터를 오퍼랜드 필드에 직접 명시하는 방법이다. 일반적으로 CPU 외부에 있는 메모리에 접근하는 것 보다 CPU 내부에 있는 레지스터에 접근하는 것이 더 빠르다. 직접 주소 지정 방식과 비슷하게, 표현할 수 있는 레지스터의 크기에 제한이 생길 수 있다.

🔎 레지스터 간접 주소 지정 방식

레지스터 간접 주소 지정 방식(register indirect addressing mode)은 연산에 사용할 데이터를 메모리에 저장하고, 그 주소(유효 주소)를 저장한 레지스터를 오퍼랜드 필드에 명시하는 방법이다. 간접 주소 지정 방식과 비슷하지만, 메모리에 접근하는 횟수가 한 번으로 줄어든 것이 차이점.

This post is licensed under CC BY 4.0 by the author.

[CS] Chapter 02. 데이터

[CS] Chapter 04. CPU의 작동 원리