본문 바로가기

IT개발/컴퓨터구조

컴퓨터 구조에 대한 설명(2-3) / Direct모드 와 InDirect모드

자, 이제 Direct와 InDirect 모드에 대해 알아보자. ^^

 

※ Direct모드 와  InDirect모드

 

지금까지 우리는 명령어를 디자인하면서 많은 것을 이루었다.

16비트로 디자인된 명령어에 참으로 많은 정보들을 담도록 디자인했으니 말이다.

 

하지만 한 가지 문제점이 있다. 

 

이 문제점에 대해, 그리고 이 문제를 해결하기 위한 접근방법에 관심을 두길 바란다. ^^

다시 한번 말하지만 지금 여기서 언급되는 문제점은 실제 cpu에서도 유사하게 존재하는 것들이다.

 

 

 - Direct모드의 문제점과   InDirect모드의 제안

 

하나의 명령어에 여러정보를 담다보니, 우리는 표현가능한 데이터 크기에 제한이 따른다는 것을 알게 되었다.

 

예를 들어보자.

LOAD명령어는 세개의 비트수로 표현되는 destination(8)은 문제가 안된다. 왜냐면 레지스터가 8개 뿐이다.

하지만, 메인 메모리의 주소값을 나타내는 source부분에서는 문제가 생길 수 있다.  이 부분에 총 8비트가 할당되어

표현할 수 있는 범위가 0x0000 ~ 0x00ff까지가 전부이기 때문이다.

 

만약 범위를 초과하는 0x0100번지에 저장된 데이터는 절대 참조를 할 수없게 된다.

 

이런 메모리 접근 방식을 우리는 Direct모드라 한다. 하지만 이 방법은 메모리의 모든 영역에 대한 접근이 불가능하다.

왜냐면, Direct모드로 메모리 접근시 , 할당된 비트수 안에서 표현가능한 범위의 메모리 영역만 접근이 가능하기 때문이다.

 

그럼 해결책은? InDirect 모드를 알아보자~

 

 

 

※ InDirect모드에 대한 이해

 

InDirect 모드의 등장은 메모리 접근방법에 다양성을 부여한다. 그럼 이제부터 알아보자.

 

( 상황 1 ) = Direct

동생에게 "놀라운 새우깡"사와라고 부탁한다고 가정해보자. 이런데 나는 이 제품이 바로 집앞

"멋있는 슈퍼마켓"에 판매하고 있음을 알고 있다. 그래서 직접 동생에게 이렇게 말한다.

 

" 야! 멋있는 슈퍼마켓에서 놀라운 새우깡 좀 사와"

 

( 상황 2 ) = InDirect

그런데 이번엔 나와 동생이 이 제품이 어디서 파는지 모른다. 그러나 건너방에 있는 큰 형은

이것을 지난번에 구입한 적이 있다. 그래서

 

" 큰형한테 물어보고, 놀라운 새우깡좀 사와라"

 

 

첫 번째 상황은 Direct, 두 번째는 InDirect 다. 앞에서 LOAD 명령어에서는 레지스터에

저장할 데이터가 존재하는 주소를 직접적으로 표현했는데, 반대로 InDirect 모드라 한다면,

명령어에서 지정하는 번지에 저장된 값을 주소값으로 참조하게 된다.

 

0x30 번지에 10이라는 값이 있다면 0x10번지에 저장된 값을 주소값으로 참조해서 값을 읽어오란 것이다.

 

LOAD r1,  0x10

LOAD r1, [0x10]

 

[] 기호로 주소값을 감싸게 되면, 이는 Indirect모드연산을 의미하게 된다.  (그냥 우리가 만든 규칙이라 가정해보자)

 

 

그렇다면 Indirect모드 명령어는 바이너리 코드로 어떻게 표현하면 좋을까? 밑을 보면 다음과 같은

구조로 바이너리가 형성되는 것을 알 수 있다.

 

--> 문제는 source로 저장된 주소값이 Direct 모드를 말하는지, Indirect모드를 말하는지 모르는 것이다.

 

 

-----------------------------------------------------

예약(2)   LOAD(3)  destination(3)   source(8)

              110            011             00000111 

-----------------------------------------------------

 

앞서 예약비트(2)를 남긴것을 기억하는가? 이영역을 활용해보자.

 

11을 Indirect로 표현할지 01을 Indirect로 표현할지는 당신의 자유다.

 

 

 

 

※ InDirect모드 활용 예제

 

이번엔 InDirect가 활용되는 예를 하나 들어보자.

기존방식의 Direct모드로는 다음은 연산은 할 수 없다.

 

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

int b = 20;  // 0x0100 번지 할당  <------ 우리는 LOAD 명령어에서 source(8)을 8비트로 할당했다. 따라서 0x00 ~ 0xff가 최대범위다

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

c = a + b;

 

하지만, 이건  Indirect모드를 이용하면 해결이 가능하다.

 

요지는 LOAD r2, 0x0100  ]  이걸 대신할 명령어를 조합해 보는거다.

 

우선 0x100은 십진수로 256 닌까, 이 숫자를 만들어 내야 한다.

 

MUL  r0, 4, 4         // r1에는 데이터 0x0100 이 저장되있으므로 r0에 연산결과 저장 

MUL  r2, 4, 4

MUL  r3, r0, r2

 

일단 r0에 16을 저장하고, r2에도 16을 만들어 저장한다.

그리고 마지막에 이 두 레지스터에 저장된 값을 곱해서 그 결과 256을 r3에 저장한다.

 

숫자만 조합하는거닌까, 다양한 정답이 존재한다. 하염없이 ADD명령어만 사용해도 256은 만들수 있다.

 

이제 r3에 저장된 주소값을 참조해 메모리로부터 값을 읽고, 레지스터 r2에 저장하는 일만 남았다.

어떻게 구성하면 되겠는가? 혹시 다음과 같이 생각했는가?

 

LOAD   r2,  r3

 

하지만, r3에는 메모리 주소정보가 와야한다. 우리가 명령어를 디자인했으니 위에서 확인해봐라.

 

참조)  LOAD 명령어의 두 번째 피연산자로 레지스터 정보도 올 수 있게 디자인 한다면, 주소값이 직접오는 경우와

         레지스터 정보가 오는 경우를 구분하기 위해서 또 하나의 비트를 희생시켜야 한다. 즉, 명령어 개수를 늘리는 것만이 최선은

         아니다.

 

그럼 Indirect모드의 메모리 참조방식이 어떻게 문제해결의 키가 되는지 명령어를 조합해보자.

 

STORE  r3,  0x0030                     // 일단 r3에 저장된 데이터를 0x0030에 저장한다.

LOAD    r2,  [0x0030]                  // 그리고 메인 메모리를 Indirect모드로 참조해서 값을 읽어오도록 하자.

 

드디어 0x0100 번지에 저장된 데이터를 레지스터 r2에 저장하는데 성공했다.

 

c = a + b; 에 해당하는 명령어의 조합은 다음과 같게 된다.

 

---------------------------------------------------------------------------

LOAD  r1,   0x0010

 

MUL  r0, 4, 4         // r1에는 데이터 0x0100 이 저장되있으므로 r0에 연산결과 저장 

MUL  r2, 4, 4

MUL  r3, r0, r2

 

STORE  r3,  0x0030

LOAD    r2,  [0x0030]

 

ADD   r3,  r1,  r2

---------------------------------------------------------------------------

 

자,  어떤가 오늘은 여기까지다. 정확히 1시간 동안 정리했다. 이제 집으로 가자. 

오늘임무 달성 고고씽~