테마
CPU의 동작
CPU는 메모리에서 명령어를 하나 가져와 해석하고 실행하는 일을 끝없이 되풀이한다. 이 반복을 맡는 부품이 계산하는 ALU(Arithmetic Logic Unit, 산술 논리 연산 장치), 지시하는 제어 장치(control unit), 값을 잠깐 담는 레지스터(register)다. 이 반복을 잠시 끊고 급한 일을 먼저 처리하게 하는 인터럽트(interrupt)는 다음 문서에서 다룬다.
CPU를 이루는 세 부품
- ALU는 덧셈·뺄셈 같은 산술 연산과 AND·OR 같은 논리 연산을 실제로 수행하는 회로다. 계산 결과와 함께 "결과가 0인지, 음수인지, 넘쳤는지" 같은 상태 정보도 내보낸다.
- 제어 장치는 명령어를 해석해, 클럭(clock) 신호가 한 번 뛸 때(한 박자)마다 ALU·레지스터·메모리에 무엇을 할지 제어 신호를 보낸다. 직접 계산하지는 않고 지휘만 한다.
- 레지스터는 CPU 안에 있는 아주 작고 가장 빠른 저장 공간이다. ALU가 계산할 값과 결과, 다음에 실행할 명령어 위치처럼 지금 당장 필요한 값만 담는다.
주요 레지스터
프로그램 카운터(program counter)는 명령어를 하나 가져올 때마다 다음 명령어 주소로 자동으로 늘어난다. 조건에 따라 다른 곳으로 건너뛰는 분기(branch) 명령어와 함수 호출 명령어는 이 값을 다른 주소로 바꿔 실행 흐름을 옮긴다. 면접과 국가기술자격 시험인 정보처리기사에 자주 나오는 레지스터는 다음과 같다.
| 레지스터 | 담는 것 |
|---|---|
| 프로그램 카운터 | 다음에 가져올 명령어의 메모리 주소 |
| 명령어 레지스터(instruction register) | 방금 가져와 제어 장치가 해석·실행 중인 명령어 |
| 메모리 주소 레지스터(MAR, Memory Address Register) | 읽거나 쓸 메모리 주소 |
| 메모리 버퍼 레지스터(MBR, Memory Buffer Register) | 메모리와 주고받는 데이터 |
| 범용 레지스터(general-purpose register) | 계산에 쓰는 값과 결과 |
| 플래그 레지스터(flag register) | 직전 연산 결과의 상태(0·음수·자리올림 등) |
| 스택 포인터(stack pointer) | 함수 호출 기록을 쌓는 메모리 영역인 스택(stack)의 꼭대기 주소 |
명령어의 구조와 주소 지정 방식
기계어(machine code) 명령어 하나는 크게 두 부분으로 나뉜다. 연산 코드(opcode)는 "더하라, 옮겨라, 점프하라"처럼 무엇을 할지를 나타낸다. 피연산자(operand)는 연산에 쓸 값이나, 그 값이 있는 위치를 나타낸다.
피연산자 칸은 좁아서 큰 값이나 긴 주소를 직접 다 담기 어렵다. 그래서 "피연산자 칸의 내용을 어떻게 해석해 실제 값을 찾을지"를 정한 여러 주소 지정 방식(addressing mode)을 둔다.
| 방식 | 피연산자 칸의 내용 | 실제 값의 위치 |
|---|---|---|
| 즉시 | 값 자체 | 명령어 안 |
| 직접 | 메모리 주소 | 그 주소 |
| 간접 | 값의 주소가 적힌 칸의 주소 | 두 번 찾아간 곳 |
| 레지스터 | 레지스터 이름 | 그 레지스터 |
| 레지스터 간접 | 주소를 담은 레지스터 이름 | 레지스터가 가리키는 주소 |
| 변위 | 기준 레지스터와 더할 값 | 기준 주소 + 값 |
즉시(immediate) 방식은 메모리에 갈 필요가 없어 가장 빠르지만 담을 수 있는 값이 작다. 간접(indirect) 방식은 메모리를 두 번 읽어 느리다. 대신 좁은 피연산자 칸이 아니라 메모리 칸 하나를 통째로 써서 주소를 담으므로 더 넓은 주소를 가리킬 수 있다.
변위(displacement) 방식은 기준 주소에 피연산자 값을 더해 실제 주소를 만든다. 프로그램 카운터를 기준으로 삼으면 상대 주소(relative addressing)가 되어, 프로그램이 메모리 어디에 올라가도 "지금 위치에서 몇 칸 뒤"로 점프할 수 있다. 배열(array) 시작 주소를 기준으로 삼으면 인덱스 주소(indexed addressing)가 되어, 더하는 값만 바꿔 배열의 여러 칸을 차례로 읽을 수 있다.
명령어 사이클
CPU가 명령어 하나를 처리하는 반복 과정을 명령어 사이클(instruction cycle)이라 한다. 가장 기본은 두 단계다.
- 인출(fetch): 프로그램 카운터가 가리키는 주소의 명령어를 메모리에서 읽어 명령어 레지스터에 담고, 프로그램 카운터를 다음 명령어로 넘긴다.
- 실행(execute): 제어 장치가 명령어를 해석하고, ALU가 계산하거나 메모리를 읽고 쓰는 등 명령어가 시킨 일을 한다.
정보처리기사 교재는 여기에 두 단계를 더해 네 단계로 설명한다. 간접 단계는 간접 주소 지정처럼 피연산자 주소를 한 번 더 읽어야 할 때, 인터럽트 단계는 실행을 마친 뒤 처리할 인터럽트가 있을 때만 들어간다.
다이어그램 로딩…
이어지는 내용은 CPU의 동작 2에서 다룬다.
면접 포인트
- "CPU 구성 요소는?" → ALU(계산), 제어 장치(해석·지휘), 레지스터(가장 빠른 저장 공간).
- "프로그램 카운터의 역할은?" → 다음 명령어 주소. 인출할 때마다 늘고, 분기·호출이 바꾼다.
- "명령어 사이클은?" → 인출 → (간접) → 실행 → (인터럽트). 기본은 인출·실행 반복.
