CPU는 기억장치에 저장되어 있는 명령어을 인출하여 실행해 작업을 수행한다. CPU가 한 개의 명령어를 실행하는 전체 과정을 명령어 사이클이라고 한다. 명령어 사이클은 명령어 인출과 명령어 실행 단계로 나뉜다.

명령어 사이클은 프로그램이 종료되거나 중단될 때까지 반복 수행한다.
프로그램 카운터(Program Counter : PC)
다음에 인출될 명령어릐 주소를 가지고 있는 레지스터이다.
누산기(Accumulator : AC)
데이터를 일시적으로 저장하는 레지스터이다. AC의 비트 수는 단어 길이와 같다.
명령어 레지스터(Instruction Register : IR)
가장 최근에 인출된 명령어가 있는 레지스터이다.
기억장치 주소 레지스터(Memory Address Register : MAR)
PC에 저장된 명령어 주소가 시스템 버스로 출력되기 전에 일시적으로 저장되는 주소 레지스터이다. 이전 글에 CPU의 내부 버스는 외부 시스템 버스와 직접 연결되지 않는다고 했는데 이 레지스터가 시스템 주소 버스와 직접 연결되어 있다.
기억장치 버퍼 레지스터(Memory Buffer Register : MBR)
기억장치에 저장될 데이터 혹은 기억장치로부터 읽혀진 데이터가 일시적으로 저장되는 레지스터이다. (MAR과 나머지 설명 동일)
CPU가 기억장치에서 명령어를 읽어오는 과정이다.
마이크로-연산으로 표현하면 아래와 같다.
t0 : MAR <- PC
t1 : MBR <- M[MAR], PC <- PC + 1
t2 : IR <- MBR
t는 CPU의 클록의 각 주기를 의미한다. 명령어 인출은 3개의 클록이 걸린다. CPU의 클록 주파수가 1GHz(=1ns)라고 가정하면 인출 사이클은 3ns가 걸린다.
인출 사이클에서 PC의 내용을 CPU 내부 버스를 통해 MAR에 보낸다. 이제 MAR과 연결된 시스템 주소 버스를 통해 기억장치에서 해당 주소에 저장된 명령어를 읽어 MBR로 적재하고 동시에 PC의 값을 1증가 시킨다. 여기서 1은 word를 의미한다. 그리고 MBR에 저장된 명령어 코드를 IR로 적재 시킨다.
실행 사이클은 제어 유니트에서 명령어를 해독하고 그결과에 따하 필요한 연산을 수행한다. 이때 연산은 다양한데 크게 4가지로 분류한다.
그전에 명령어의 구조를 살짝 보자. 명령어는 연산코드와 오퍼랜드로 구성되어 있다.
| 연산 코드 | 오퍼랜드(addr) |
|---|
연산코드는 CPU가 실행할 연산을 지정해주고 오퍼랜드는 명령어가 사용할 데이터가 저장되어 있는 기억장치의 주소를 나타낸다.
데이터 이동
CPU와 기억장치 혹은 I/O장치 간에 데이터를 이동한다.
LOAD addr 명령어
t0 : MAR <- IR (addr)
t1 : MBR <- M[MAR]
t2 : AC <- MBR
데이터 처리
데이터에 대해 산술 혹은 논리 연산을 수행한다.
ADD addr 명령어
t0 : MAR <- IR (addr)
t1 : MBR <- M[MAR]
t2 : AC <- AC + MBR
데이터 저장
연산결과 데이터 혹은 입력장치로부투 읽은 데이터를 기억장치에 저장한다.
STA addr 명령어
t0 : MAR <- IR (addr)
t1 : MBR <- AC
t2 : M[MAR] <- MBR
프로그램 제어
프로그램의 실행 순서를 결정한다. JUMP addr 명령어는 오퍼랜드에 분기 목적지의 주소를 가리키기 때문에 한 주기만에 끝난다.
JUMP addr 명령어
t0 : PC <- IR(addr)
인터럽트
CPU가 현재 처리 순서를 중단하고 다른 프로그램을 처리하도록 하는 매커니즘이다. 정상적인 프로그램의 동작을 방해하는 동작이만 인터럽트는 반드시 필요한 기능이다. (긴급한 상황)
인터럽트 서비스 루틴(interrupt service routine : ISR)
인터럽트를 처리해주기 위한 프로그램을 말한다.
CPU는 인터럽트 요구를 인식할 수 있어야 하고 어떤 장치가 인터럽트를 요구했는지 구분하고 해당 인터럽트 서비스 루틴을 실행해야 한다. 그리고 인터럽트에 대한 처리가 끝나면 CPU는 원래 프로그램으로 돌아가야한다. 이를 위해 CPU는 실행 사이클이 끝나면 인트럽트 사이클시작한다. 인터럽트 요구 신호가 들어왔는지 확인해서 들어왔다면 PC에 적재된 현재 동작 중인 프로그램의 다음 명령어를 스택에 저장한다. 이는 인터럽트 서비스 루틴이 종료되면 돌아오기 위한 것이다. 요구된 인터럽트 서비스 루틴을 실행하기 위해 루틴의 시작 주소를 PC에 적재한다. 이를 인터럽트 사이클이라고 한다.
t0 : MBR <- PC
t1 : MAR <- SP, PC <- ISR 의 시작 주소
t2 : M[MAR] <- MBR, SP <- SP - 1=
SP는 스택 포인터를 의미한다.
단, 인터럽트 사이클을 실행하기 전에 인터럽트가 가능한 상태로 세트되어 있는지 확인한다. 이때 인터럽트를 받을 수 있는 상태로 세트되어 있으면 '인터럽트 가능'상태라 하고 받을 수 없는 상태면 '인터럽트 불가능'상태라고 한다. 이 상태는 CPU가 변경할 수 있다. 인터럽트 사이클에서 유의해야할 점이 있는데 AC 레지스터에 어떤 값이 적재되어 있는데 인터럽트 사이클이 실행되는 동안 AC 레지스터의 값이 바뀌었다면 문제가 발생할 수도 있다. 그래서 인터럽트 서비스 루틴이 시작단계에서 레지스터의 내용을 스택에 저장했다가 마지막 단계에서 복원시켜주는 과정이 필요하다.
인터럽트 서비스 루틴이 실행되고 있는데 다른 외부 장치에서 인터럽트 요구를 발생하는 경우이다. 두가지 방법으로 처리가 가능하다.
인출 사이클과 실행 사이클 사이에 위치한다. 간접 사이클은 실행 사이클에서 사용될 데이터의 실제 주소를 기억장치로부터 읽어오는 과정으로 항상 실행되는 것은 아니다. 명령어 내에 특정 비트가 1인 경우에만 실행된다. 명령어 내에는 연산에 필요한 데이터를 읽어오기 위한 기억장치의 주소를 포함하고 있는데 어떤 명령어에 경우에는 필요한 데이터가 저장된 기억장치의 주소가 아니라 필요한 데이터의 주소가 저장된 기억장치의 주소를 가리키는 경우가 있다. 이를 간접 주소지정 방식에서 이라고 하고 간접 사이클은 이때 사용된다.
t0 : MAR <- IR(addr)
t1 : MBR <- M[MAR]
t2 : IR(addr) <- MBR