본문 바로가기

CS/컴퓨터구조(Mano)

[컴퓨터구조] ch.8 중앙처리장치 (2) 명령어 형식

Mano의 컴퓨터시스템구조 제3판, 프로텍 미디어, 김종상 옮김 도서를 정리, 요약하는 글입니다.

 

1. 레지스터 구조

- 명령어 코드의 비트는 필드라고 불리는 몇 개의 그룹으로 나뉜다. 수행해야할 연산을 명시한 연산 코드 필드, 메모리의 주소나 레지스터를 지정하는 주소 필드, 피연산자나 유효 주소가 결정되는 방법을 나타내는 모드 필드 등이 있다. 여기서는 주소 필드에서 대해서 다루겠다.

- k비트로 이루어진 레지스터의 주소는 2k개만큼의 레지스터를 지정할 수 있다. 명령어 형식에서 주소 필드는 컴퓨터 내부의 레지스터 구성에 따라 달라진다. 컴퓨터의 CPU는 단일 누산기 구조, 범용 레지스터 구조, 스택 구조 3가지로 나뉜다.

 

(1) 누산기 구조

- 모든 명령어의 수행은 내장된 누산기 레지스터(AC)와 이루어진다. 따라서 명령어는 1개의 주소 필드를 가진다.

ADD X 라는 명령어는 X가 피연산자의 주소가 되며 이 명령은 AC ← AC + M[X]가 될 것이다.

 

(2) 범용 레지스터 구조

- 이 명령어 형식은 2, 3개의 레지스터 주소 필드를 가진다. ADD, R1, R2, R3라고 하면 R1 R2 + R3가 된다. 만약 ADD R1, R2라고 하여 주소 필드 하나가 줄어들면 이는 목적지 레시스터가 소스 레시스터 중 하나와 같은 것으로 R1 R1 + R2가 된다. 

- 2개의 주소 필드를 쓴다면 MOV, R1, R2라고 하여 R1  R2 명령을 나타낼 수 있다. 혹은 필드가 레지스터가 아닌 메모리를 지정할 수도 있다. ADD, R1, X라 하면 R1  R1 + M[X]라 할 수 있다. 

 

(3) 스택 구조

- 주소 필드가 필요한 push, pop 명령어가 있어야 한다. PUSH X 명령어는 X 주소에 잇는 값을 스택 top에 push 하라는 것이다. 여기서 연산에 관계된 명령어는 주소 필드가 필요없다. 스택의 top에 있는 두 개의 값들이 연산에 쓰이기 때문이다. 

 

2. 명령어 형식

(1) 3-주소의 명령어

- 각 주소 필드가 레지스터를 지정할 수도 있고, 메모리 주소를 지정할 수 있다. 예를 들어, 어셈블리어로 X = (A + B) * (C + D)를 3주소 명령어로 표현하면 다음과 같다.

 

ADD        R1, A, B          R1  M[A] + M[B]

ADD        R2, C, D         R2  M[C] + M[D]

MUL        X, R1, R2        M[X]  R1 * R2

 

- 이의 장점은 프로그램의 길이를 짧게 할 수 있다는 것이다. 단점은 이진 코드로 명령어를 나타낼 때 너무 많은 비트가 필요하다는 것이다. 

 

(2) 2-주소의 명령어

- 가장 흔하게 사용되는 형식이다. 마찬가지로 각 주소 필드는 레지스터나 메모리 주소를 지정할 수 있다. X = (A + B) * (C + D)를 2주소 명령어로 표현하면 다음과 같다.

 

MOV        R1, A       R1 M[A]

ADD         R1, B       R1 R1 + M[B]

MOV        R2, C       R2 ← M[C]

ADD         R2, D       R2 R2 + M[C]

MUL         R1, R2     R1 ← R1 *R2

MOV        X, R1       M[X] ← R1

 

(3) 1-주소의 명령어

- 모든 데이터 처리가 누산기(AC)에 의해 처리된다.  X = (A + B) * (C + D)를 1주소 명령어로 표현하면 다음과 같다.

 

LOAD      A          AC  M[A]

ADD        B          AC  AC + M[B]

STORE    T          M[T]   AC

LOAD      C          AC    M[C]

ADD        D          AC   AC + M[D]

MUL        T          AC   AC * M[T]

STORE    X          M[X]    AC

 

(4) 무주소 명령어

- 스택 구조의 컴퓨너는 ADD, MUL 등의 명령어에서 주소 필드를 사용하지 않는다. 오로지 push, pop 명령에서 쓰이는 스택과 피연산자 사이의 정보 전달을 위한 하나의 주소 필드만 필요하다. 무주소라는 이름은 연산 명령어에서 주소 필드가 없기 때문이다. X = (A + B) * (C + D)는 다음과 같이 표현한다.

 

PUSH      A          TOS  ←  A

PUSH      B          TOS  ←  B

ADD                     TOS  ←  (A + B)

PUSH      C          TOS  ←  C

PUSH      D          TOS  ←  D

ADD                     TOS  ←  (C + D)

MUL                     TOS  ←  (A + B) * (C + D)

POP        X           M[X]  ←  TOS

 

- TOS는 top of stack 이다. 스택을 사용할 경우 역 polish 형태를 써서 표현해야 한다. 

 

(5) RISC 명령

- RISC 프로세서의 명령어 집합은 메모리와 CPU 사이의 통신을 할 때 load와 store 명령어만 사용하도록 제한한다. 먼저, 메모리에서 필요한 데이터를 레지스터로 로드한다. 이때, 메모리와의 통신은 로드 명령어와 스토어 명령어를 통해서만 이루어진다. 다른 모든 명령어들은 메모리 참조 없이 CPU의 레지스터 안에서 실행된다. 메모리에서 값을 로드한 후, 이후의 연산은 전부 레지스터 간의 연산이 된다. 레지스터 간의 연산은 메모리 접근보다 속도가 빠르기 때문에 레지스터 연산에 집중시키는 것이 RISC의 성능을 높이는 것이다.

- RISC CPU를 위한 프로그램은 하나의 메모리와 레지스터를 지정하는 주소를 가진 LOAD, STORE 명령어와 3개의 프로세서 레지스터를 지정하여 표현한다. X = (A + B) * (C + D)는 다음과 같이 표현한다.

 

LOAD        R1, A                  R1  ←  M[A]

LOAD        R2, B                 R2  ←  M[B]

LOAD        R3, C                 R3  ←  M[C]

LOAD        R4, D                 R4  ←  M[D]

ADD          R1, R1, R2         R1  ← R1 + R2

ADD          R3, R3, R4        R3  ← R3 + R4

MUL          R1, R1, R3         R1  ← R1 * R3

STORE      X, R1                 M[X]  ←  R1