1. CPU의 내부 구성요소

 CPU의 내부 구성요소에는 크게 산술논리연산장치, 제어장치, 레지스터가 있다.

 

1) 산술논리연산장치 (Arithmetic and Logical Unit: ALU)

 이름 그대로 산술논리연산장치는 산술연산과 논리연산을 수행한다. 산술연산은 더하기, 빼기, 곱하기, 나누기와 같은 것이며 논리연산은 AND, OR, NOT과 같은 것들이다.

 

2) 제어장치

 제어장치는 CPU 내의 명령어를 해석하여 제어 신호를 보낸다. 

 

3) 레지스터

 레지스터는 일종의 기억장치인데, 기억장치 중 액세스 속도가 가장 빠르며, 종류도 많다. 레지스터의 대표적인 종류로는 프로그램 카운터(Program Counter), 명령어 레지스터(Instruction Register), 기억장치 주소 레지스터(Memory Address Register), 기억장치 버퍼 레지스터(Memory Buffer Register)가 있다. (이외에도 데이터 레지스터, 주소 레지스터, 프로그램 상태 레지스터 등 레지스터의 종류는 아주 많다.)

 

4) 버스

버스는 CPU와 주변장치간 데이터를 주고 받을 때 사용하게 된다. 버스의 종류로는 제어 버스, 주소 버스, 데이터 버스가 있다.

2. CPU의 명령어 처리

 위의 내용을 바탕으로 CPU의 구성요소들이 어떻게 명령어를 처리하는지 알아보자.

C언어로 작성된 덧셈 프로그램

 위 사진은 C언어로 작성된 덧셈 프로그램이다. 변수 a에 정수값 1을 저장하고, 변수 b에는 정수값 2를 저장하고 둘을 더한 뒤에 더한 값을 sum_이라는 변수에 저장한다. sum_에는 정수값 3이 저장될 것이다. CPU는 컴파일러를 이용하여 위 내용을 0과 1로 이루어진 기계어로 변환한다. 

어셈블리어로 변환한 덧셈 프로그램

 위 사진은 C언어로 작성된 내용을 어셈블리어로 변환한 것이다. (어셈블리어는 기계어와 다르며, 기계어를사람이 이해하기 쉽도록 기호화한 언어이다.) 

 메모리 10번지에 변수 a가 저장되었고, 메모리 20번지에 변수 b가 저장되었다. 1행에서 메모리 10번지에 저장된 변수 a를 레지스터1로 가져온다. 마찬가지로 2행에서 메모리 20번지에 저장된 변수 b를 레지스터 2로 가져온다. 3행에서는 레지스터1과 레지스터2의 값을 더해 레지스터 3에 저장한다. 마지막으로 4행에서는 레지스터3에 저장된 값을 메모리 30번지로 옮긴다. 

 이때 제어장치는 'LOAD','MOVE','ADD'에 대응하는 신호를 보내며, 산술논리연산장치는 덧셈을 수행한다.

어셈블리어로 변환한 덧셈 프로그램 - 첫 번째 행

 위에서 언급했던 레지스터인 프로그램 카운터, 명령어 레지스터, 기억장치 주소 레지스터, 기억장치 버퍼 레지스터의 역할을 위 첫번째 행의 실행 과정을 통해 알아볼 것이다. 

 우선 프로그램 카운터는 다음에 실행할 기계어의 위치를 저장하는 역할을 한다. 따라서 'LOAD' 명령어가 저장된 위치를 가져올 것이며, 이 위치는 제어장치에 전송된다.

 제어장치는 명령어 레지스터에 위치를 보내고, 명령어 레지스터는 명령을 해석하여 메모리에 있는 데이터를 가져오라는 신호를 보낸다.

 메모리 주소 레지스터는 이름 그대로 메모리 주소를 일시적으로 저장하는 역할을 한다. 따라서 메모리 주소 레지스터에는 메모리 주소 10이 저장된다. 

 메모리 버퍼 레지스터는 메모리에 저장된 내용을 읽어와 일시적으로 저장하는 역할을 한다. 따라서 메모리 버퍼 레지스터에는 메모리 주소 10에 저장된 값인 정수 1이 저장될 것이다.

 

3. CPU의 명령어 형식

1) 명령어의 구성요소

 명령어의 구성요소에는 연산 코드(Operation Code), 오퍼랜드(Operand)가 있다. 연산 코드는 수행될 연산을 지정하며, 오퍼랜드는 연산을 수행하는데 필요한 데이터나 데이터 주소를 저장한다. 

 

2) n주소 명령어

 명령어의 구성에 따라 명령어를1주소, 2주소, 3주소 명령어 등으로 구분할 수 있다. (0주소 명령어도 존재하는데, 이 경우는 기억장치 주소를 달지 않고 연산 코드만을 사용한다.

 

연산 코드 기억장치 주소

 위 표는 1주소 명령어의 명령어 구성이다. 연산 코드와 기억장치 주소를 저장하며, 연산 코드에 따라 명령을 수행한 후 기억장치 주소에 수행한 결괏값을 저장한다.

 

연산코드 레지스터1 레지스터2

 

연산코드 레지스터1 기억장치 주소

   위 표들은 2주소 명령어의 명령어 구성이다. 2주소 명령어의 경우 첫번째 경우처럼 두 개의 레지스터 오퍼랜드를 가질 수도 있고 두번째 겨우처럼 한 오퍼랜드는 레지스터, 한 오퍼랜드는 기억장치 주소를 가질 수도 있다. 첫번째의 경우 레지스터 1과 레지스터2에 저장된 값을 합쳐 레지스터1에 저장하는 동작이 예시가 될 수 있겠다. 두번째의 경우 기억장치 주소에 있는 값을 가져와 레지스터1과 더한 후 레지스터1에 저장하는 동작이 예시가 될 수 있을 것이다.  (이때 연산코드는 ADD가 될 것이고, 레지스터1에 저장되었던 값은 소실된다.)

 

연산코드 레지스터1 레지스터2 레지스터3

 마지막으로 3주소 명령어의 명령어 구성이다. 2주소에서는 레지스터가 두 개밖에 존재하지 않아 한 레지스터의 값이 소실되었지만 3주소 명령어의 경우는 그렇지 않다. 레지스터2와 레지스터3의 값을 더하여 레지스터1에 저장하는 것이 3주소 명령어 동작 예시가 되겠다. (이때도 연산코드가 ADD라고 가정한다.)

+ Recent posts