프로세서는 요리책을 한 줄씩 읽고 그대로 하는 요리사와 같다. 다음 줄을 읽어 오고(인출), 읽은 대로 한다(실행). 이 두 걸음을 전원이 꺼지거나, 고칠 수 없는 오류가 나거나, “멈춰라” 명령어를 만날 때까지 되풀이한다. 단순해서 빠르지만, 요리사가 혼자 순서대로만 움직이기 때문에 느린 장치를 기다리는 동안에는 손을 놓게 된다.
예시로 보기
작은 가상 기계로 “940번지 값과 941번지 값을 더해 941번지에 넣는다”를 실행해 본다.
- 명령어 하나는 16비트다. 앞 4비트가 할 일(연산 코드), 뒤 12비트가 주소다.
- 연산 코드는 세 개만 쓴다.
1= 메모리 값을 AC로 읽기,2= AC 값을 메모리에 쓰기,5= 메모리 값을 AC에 더하기. - AC(누산기)는 계산 중간값을 잠깐 담는 레지스터 하나다.
- 주소와 값은 모두 16진수로 적는다.
명령어는 300·301·302번지에 1940, 5941, 2941이 있다. 데이터는 940번지에 0003, 941번지에 0002가 있다. 실행하면 아래처럼 된다.
| 단계 | 하는 일 | PC | IR | AC | 메모리 변화 |
|---|---|---|---|---|---|
| 1 인출 | 300번지의 1940을 IR에 싣고 PC를 1 늘린다 |
301 | 1940 | — | |
| 2 실행 | 1 = 읽기. 940번지 값 3을 AC에 |
301 | 1940 | 0003 | |
| 3 인출 | 301번지의 5941을 가져온다 |
302 | 5941 | 0003 | |
| 4 실행 | 5 = 더하기. AC + 941번지 값 = 3 + 2 |
302 | 5941 | 0005 | |
| 5 인출 | 302번지의 2941을 가져온다 |
303 | 2941 | 0005 | |
| 6 실행 | 2 = 쓰기. AC 값을 941번지에 |
303 | 2941 | 0005 | 941번지 ← 0005 |
정확히 말하면
명령어 하나를 처리하는 데 드는 일을 통틀어 명령어 사이클이라고 부른다. 인출 단계와 실행 단계로 나뉜다.
flowchart LR
S([시작]) --> F[인출 단계<br/>PC가 가리키는 명령어를 IR로<br/>PC를 1 늘림]
F --> E[실행 단계<br/>IR의 명령어대로 함]
E --> F
E --> H([멈춤])
- 인출. PC가 가리키는 주소에서 명령어를 읽어 IR에 넣는다. 따로 지시가 없으면 PC를 1 늘려서, 다음 사이클에는 바로 다음 주소의 명령어를 가져온다. 이때 실제로는 MAR과 MBR을 거치지만 그림에서는 생략한다.
- 실행. 명령어는 네 종류 중 하나 또는 그 조합이다.
| 종류 | 하는 일 |
|---|---|
| 프로세서–메모리 | 프로세서와 메모리 사이에서 데이터를 옮긴다 |
| 프로세서–입출력 | 입출력 모듈을 거쳐 바깥 장치와 데이터를 옮긴다 |
| 데이터 처리 | 산술·논리 연산을 한다 |
| 제어 | 실행 순서를 바꾼다. PC에 새 주소를 넣어 다른 곳의 명령어를 가져오게 한다 |
가상 기계의 연산 코드는 4비트라서 \(2^4 = 16\)가지 명령을 만들 수 있다. 주소는 12비트라서 \(2^{12} = 4096\)칸(4K 워드)을 바로 가리킬 수 있다.
활용
- 이 사이클에 “인터럽트가 왔는지 확인하는 단계”를 하나 더 끼우면 인터럽트가 된다. 운영체제가 끼어들 수 있는 근거가 이것이다.
- 제어 명령어가 PC를 바꾸는 방식은 2-1학기 어셈블리어의 점프·호출 명령어(JMP, CALL)와 같다.
연결
과목별 관점
어셈블리어 (2-1학기). 같은 고리를 다섯 걸음으로 잘게 나눈다. 가져오기(fetch), 뜻 알아내기(decode), 재료 가져오기(fetch operands), 실행하기(execute), 결과 저장하기(store output)다. 첫 걸음이 이 문서의 인출 단계이고 나머지 넷이 실행 단계를 나눈 것이다1. 그림으로 그리면 프로그램 카운터(PC)가 가리키는 명령어가 명령어 레지스터로 들어가고, 재료는 메모리와 레지스터에서 ALU로 가며, 결과는 레지스터나 메모리로 돌아가고 플래그가 바뀐다.
메모리에서 값을 읽는 일은 클록 한 박자에 끝나지 않는다. 메모리가 프로세서보다 훨씬 느리게 답하기 때문이다. ① 주소 버스에 주소를 올린다. ② 읽기 선(RD)을 0으로 내린다. ③ 메모리가 답할 때까지 한 사이클을 기다린다. ④ 읽기 선이 1로 돌아가면 데이터 버스에 값이 올라와 있다.
걸음을 나눠 놓으면 앞 명령어가 다음 걸음으로 넘어가는 대로 뒤 명령어를 받을 수 있다: 파이프라인과 슈퍼스칼라.
컴퓨터 구조 (2-1학기). 같은 고리를 회로의 부품과 도선으로 그린다. 인출은 “PC의 주소를 명령어 메모리에 넣어 32비트 명령어를 꺼내고, 그 옆의 가산기가 PC + 4를 구해 두는 일”이다. 실행은 그 명령어의 비트가 여러 갈래로 갈라져 레지스터 파일, ALU, 데이터 메모리를 지나는 일이다2. 이 문서의 가상 기계와 다른 점이 둘 있다.
- PC가 4씩 는다. 가상 기계는 주소 한 칸에 명령어 하나가 들어가 1씩 늘렸다. MIPS는 주소를 바이트로 세고 명령어 하나가 4바이트라서 4씩 늘린다2.
- 한 사이클에 끝내는 설계에는 IR이 없다. 명령어 메모리의 출력이 그 사이클 내내 그대로 나와 있어서 따로 담아 둘 필요가 없다. 명령어를 여러 사이클에 걸쳐 실행하는 설계에서는 꺼낸 명령어를 담아 둘 칸이 다시 필요하다. 다중 사이클 설계의 IR, 파이프라인의 단계 사이 레지스터가 그것이다3.
부품을 잇는 그림과 명령어 종류마다 지나는 길은 단일 사이클 데이터패스에 있다. 다섯 걸음으로 나눠 겹쳐 흘리는 설계는 5단계 파이프라인이다.
확인 문제
C1 인출 단계에서 일어나는 일 두 가지를 레지스터 이름을 넣어 쓰라.
답: ① PC가 가리키는 주소의 명령어를 읽어 IR에 넣는다. ② PC를 1 늘려 다음 명령어를 가리키게 한다.
C2 1940, 5941, 2941 세 명령어가 함께 하는 일을 쉬운 말 한 문장으로 쓰라.
답: 940번지 값을 941번지 값에 더해서 941번지에 저장한다. 즉 M[941] = M[940] + M[941].
흔한 오답: 명령어마다 따로 설명하는 것. 이 문제는 셋을 합친 효과를 묻는다.
C3 같은 세 명령어를 300번지부터 실행한다. 940번지에 0006, 941번지에 000A가 있다. 세 사이클이 끝난 뒤 PC, AC, 941번지 값은? (모두 16진수)
답: PC = 303, AC = 0010, 941번지 = 0010.
이유: 6 + A(=10) = 16이고, 16을 16진수로 쓰면 10이다.
흔한 오답: 0016. 10진수 합 16을 그대로 적은 것이다.
C4 프로세서는 왜 실행 단계가 아니라 인출 단계에서 PC를 늘리는가? 제어 명령어(점프)와 연결해 설명하라.
답: 인출 직후 PC를 늘려 두면 “다음 명령어는 바로 다음 주소”가 기본값이 된다. 실행 단계에서 제어 명령어가 PC에 새 주소를 넣으면 그 기본값을 덮어써서 순서가 바뀐다. 실행 단계에서 늘린다면 점프 명령어가 넣은 주소까지 1 늘어나 엉뚱한 곳으로 간다.
C5 명령어 실행을 다섯 걸음으로 나눠 차례로 쓰라. 메모리에서 값을 읽을 때 왜 클록이 여러 박자 드는가?
답: 가져오기(fetch) → 뜻 알아내기(decode) → 재료 가져오기(fetch operands) → 실행하기(execute) → 결과 저장하기(store output). 메모리가 프로세서보다 훨씬 느리게 답해서, 주소를 올리고 읽기 선을 내린 뒤 값이 올 때까지 한 사이클을 기다려야 한다.
흔한 오답: “재료 가져오기”를 빼는 것. 명령어를 가져오는 일과 그 명령어가 쓸 값을 가져오는 일은 다른 걸음이다.
C6 이 문서의 가상 기계는 인출할 때 PC를 1 늘리고, MIPS 프로세서는 4 늘린다. 왜 다른가? 301번지의 명령어 다음 명령어는 두 기계에서 각각 몇 번지에 있는가?
답: 가상 기계는 주소 한 칸에 16비트 명령어 하나가 통째로 들어가서 다음 명령어가 바로 다음 주소(302)에 있다. MIPS는 주소를 바이트 단위로 세고 명령어 하나가 32비트 = 4바이트라서, 다음 명령어는 4만큼 뒤에 있다. 다만 MIPS에서 명령어의 주소는 늘 4의 배수여야 하므로 301번지에는 명령어가 올 수 없다. 300번지의 명령어라면 다음은 304번지다.
흔한 오답: MIPS에서도 302번지라고 답하는 것. “명령어 하나만큼”과 “주소 1만큼”은 주소를 세는 단위에 따라 다르다.
-
이 문서의 인출 단계가 “명령어를 읽어 IR에 넣는 일”이라는 정의에 맞춰 나눴다. ↩
-
Princeton COS/ELE 375 (Fall 2015, David August), Lecture 8 “Control”, 슬라이드 8, 41 (PC = PC + 4, 명령어 인출의 레지스터 전송 식 IR = Memory[PC]; PC = PC + 4), https://www.cs.princeton.edu/courses/archive/fall15/cos375/lectures/08-Control.pdf. Patterson & Hennessy, Computer Organization and Design (MIPS Edition), 4장 “The Processor” ↩ ↩2
-
단일 사이클 흉내기(24_single-cycle-datapath_impl.py)가 명령어를 담아 두는 칸 없이 동작하는 것으로 확인했다. ↩