minhui study

2부 4장 -1 . 레지스터와 명령어에 대한 깊이 있는 이해 본문

컴퓨터 구조/Windows System Programming

2부 4장 -1 . 레지스터와 명령어에 대한 깊이 있는 이해

minhui 2020. 1. 22. 13:41

[목차]

1. 컴퓨터 구조의 접근 방법

2. LOAD&STORE 명령어 디자인

3. Direct 모드와 Indirect 모드

 


Section 01. 컴퓨터 구조의 접근 방법

 

> 레지스터를 디자인하자

    ① 레지스터를 몇 비트로 구성할 것인가?  

    ② 몇 개 정도로 레지스터를 구성할 것인가? 

    ③ 레지스터 각각을 무슨 용도로 사용할 것인가?

 

16비트인 8개의 레지스터로 구상해보자

[4-1] 레지스터 구조

(r4부터 각 각 또 다른 이름을 지니도록 했는데 이 4개의 레지스터들을 특수한 목적으로 사용하기 위해서 그렇게 한 것이다.

 

> 명령어 구조 및 명령어를 디자인하자

여기서 주목할 것은 레지스터와 명령어의 상관관계이다. CPU가 달라지면 명령어 구조가 달라지기 떄문에 어셈블리 언어로 구현된 프로그램은 구조가 다른 CPU로 이식이 불가능하다.

우선 16비트로 레지스터 크기를 결정하였기 때문에 명령어 길이도 16비트로 구성하는 것이 좋겠다.

[4-2] 명령어의 길이

"레지스터 r1에 있는 값과 숫자 7을 더해서 레지스터 r2에 저장하라"

다음과 같은 명령어에서 담아야 할 정보는 '덧셈', '레지스터 r1', '레지스터 r2', '숫자 7' 이다.

[4-3] 명령어 기본 구성

ADD 연산자 위를 있는 3개 비트에는 연산결과를 저장할 저장소 정보를 두는데 이곳에는 항상 레지스터 정보만 올 수 있고록 제한한다. 그리고 그 뒤를 잇는 피연산자 1,2 (각 각 4비트) 에는 레지스터 정보나 숫자가 올 수 있도록 하였다.

 

연산에 대한 정보는 3개의 비트만 할당하면 8개 정도의 연산자를 만들어 낼 수 있다. 우선 네 개 정도는 다음과 같이 정의하자. 그리고 어셈블리 명령어도 결정을 하자.

그럼 밑에와 같이 채워지게 된다.

 

[4-4] 명령어의 구성 단계(1)

각각의 레지스터를 나타내는 2진 코드이다. 

 

 

 

 

 

 

 

연산 대상이 되는 두 개의 피연산자는 숫자가 될 수도 있고, 레지스터가 될 수도 있으므로 다으모가 같은 연산이 가능하다.

- r2 = r1 + r3  

   : 레지스터 r1와 r3에 있는 값을 더해서 r2에 저장

- r2 = r1 + 4

   : 레지스터 r1에 저장된 값과 숫자 4를 더해서 r2에 저장

- r2 = 5 + r1

   : 숫자 5와 r1에 저장된 값을 더해서 r2에 저장

- r2 = 3 + 5

   : 숫자 3과 5를 더해서 r2에 저장

 

그렇다면 저장된 데이터가 숫자인지 레지스터를 표현하는 정보인지 구분할 수 있어야 하므로 피연산자에 할당된 4개의 비트 중 맨 앞의 하나의 비트를 이용한다. 즉, 0001이면 r1을 의미하는 것이고, 0001이면 숫자 1을 의미하는 것이다.

[4-5] 명령어 구성 단계(2)

지금까지 내용을 종합해보면 다음과 같다. 우선 심볼을 기반으로 프로그램을 구현한다.

 

    - 어셈블리 언어 기반의 프로그램 구현

                     ADD r2, 21, 7

    - 어셈블러에 의한 바이너리 코드 생성

                     0000101010010111

 

이 명령어가 control unit으로 전달되어 그 의미가 해석되면 CPU의 각 모듈에 명령을 내리게 된다. 그리고 각 모듈은 이 명령에 따라 적절한 연산을 진행한다. 그림에서 보면 명령어가 ir(Instruction register)에 저장되고 있음을 알 수 있다. 이처럼 ir은 다음 번에 실행하게 될 명령어를 미리 가져다 놓는 용도로 사용된다.

[4-5] 연산의 과정

Section 02. LOAD & STORE 명령어 디자인

 

> LOAD & STORE 명령어

 

"연산결과를 레지스터에만 저장할 수 있도록 하겠다"라는 의미는 즉, 모든 피연산자에는 메인 메모리의 주소값이 올 수 없다는 제약도 둔 것이다 다름없다. (숫자와 레지스터만 가능) 때문에 다음과 같은 연산을 할 수가 없다.

int a = 10;    // 0x10번지 할당

int b = 20;    // 0x20번지 할당

int c= 0;      // 0x30번지 할당

c = a + b; 

" 0x10번지(a)에 저장된 값과 0x20번지(b)에 저장된 값을 더해서 0x30번지(c)에 저장해라"

그러나 메인 메모리 주소를 피연산자로 올 수 있도록 명령어 구조를 설계하지 않았기 때문에 위의 명령어는 실행 불가이다 따라서 메인 메모리에 저장된 데이터를 레지스터로 일단 옮겨다 놓은 다음에 연산을 진행해야 한고 이 때 필요한 명령어가 바로 메인 메모리에 저장된 데이터를 레지스터로 이동시키기 위한 LOAD 명령어와 레지스터에 저장된 데이터를 메인 메모리로 이동시키기 위한 STORE 명령어 이다.

[4-6] 명령어 LOAD & STORE

LOAD는 이진 코드 110으로 정의하였으며 목적지 정보(destination)와 데이터가 존재하는 위치(source) 정보를 담을 수 있다. 따라서 명령어 해석을 다음과 같다.

           

LOAD    r3,  0x07

    ->  "0x07번지에 존재하는 데이터를 레지스터 r3에 저장하라."

 

그리고 다음과 같은 구조로 명령어가 구성된다.

[4-7] 명령어 LOAD의 바이너리 예

STORE도 마찬가지이다. 

 

STORE   r2,  0x08

    ->  "r2에 존재하는 데이터를 메인 메모리 0x08번지에 저장하라."

[4-8] 명령어 STORE의 바이너리 예

 

앞에서 간단히 제시했던 예제를 실행해보자

현재 변수 a,b,c는 각 각 메모리 공간 0x10,20,30번지에 할당되어 있따.

아래 문장들을 다시 구성해본다면 다음과 같이 된다.

LOAD r1, 0x10;    // 0x10번지에 저장된 데이터를 r1으로 이동

LOAD r2, 0x20;   // 0x20번지에 저장된 데이터를  r2로 이동

ADD r3, r1, r2;      // r1, r2에 저장된 값을 더해서 r3에 결과 저장

Store r3, 0x30; // r3에 저장된 값을 0x30번지에 저장

 

연산이 진행되는 과정은 밑의 그림을 보면 이해하기 쉬울 것이다.

 

[4-9] 메모리 참조 연산의 진행과정

 

다음 편에서는 Direct모드과 Indirect모드에 대해 설명을 하겠다.

 

출처 : 윈도우즈프로그래밍(한빛아카데미)

Comments