본문 바로가기

C, C++/뇌를 자극하는 윈도우즈 시스템 프로그래밍

[뇌를 자극하는 윈도우즈 시스템 프로그래밍] 4장 - 컴구조(2)

개요

컴퓨터 구조에 대한 이해는 프로세스와 쓰레드를 이해하는 것에도 도움이 된다.

 

CPU 디자인에 대해 생각해보며, 컴퓨터를 이해해보자.

CPU의 주요 부품은 알고있듯이, ALU, 컨트롤 유닛, 레지스터이다. 이중 레지스터 디자인해 대해서 생각해보자.

 

레지스터 디자인

1. 레지스터를 몇 비트로?

2. 몇 개 정도로 레지스터를 구성?

3. 레지스터 각각은 무슨 용도로 사용?

 

이 세가지를 중점으로 보자.

 

책에서는 간단한 예시를 위해 8개의 16비트 레지스터를 사용한다.

r0~r7으로 이름을 짓고, r5~r7는 sp, lr, pc라고 별도로 정한다.

 

명령어 디자인

레지스터를 바탕으로 명령어를 디자인한다.

레지스터 디자인에 따라 명령어 구조는 달라진다.

따라서 어셈블리 언어로 구성된 프로그램은 레지스터 종속적이기 때문에 다른 CPU로 이식이 불가능할 수 있다.

 

레지스터가 16비트이므로 레지스터를 최대한 활용하기 위해 명령어도 16비트로 구성한다.

명령어 16비트를 어떻게 알차게 사용할지 생각해보자.

 

연산자(어떤 명령을 할건지) + 저장소 + 피연산자1 + 피연산자2의 정보를 담을 수 있도록 구성한다.

 

이렇게 구성된 명령어는 컨트롤 유닛으로 전달되고, 해석되어 CPU의 각 모듈에서 실행된다.

 

추가적으로 첫번째 피연산자의 위치에는 CPU의 제약사항에 의해 레지스터 이름이 필요하다. 


LOAD & STORE 명령어 디자인

메모리를 통해 바로 연산할 수 없기 때문에 메모리에서 레지스터로 값을 불러오는 연산이 필요하다.

또한 이 연산 결과를 다시 레지스터에서 메모리에 저장하는 연산이 필요하다.

이를 각각 LOAD, STORE라고 하고 디자인하자.

 

LOAD는 연산자 심볼 + 목적지(레지스터) + 소스(메인 메모리 주소) 가 필요하다.

LOAD r3, 0x07

 

 

STORE는 연산자 심볼 + 소스(레지스터) + 목적지(메인 메모리 주소) 가 필요하다.

STORE r2, 0x08

 

 

따라서 c = a + b같은 명령을 위해서는

LOAD r1, 0x10
LOAD r2, 0x20
ADD r3, r1, r2
STORE r3, 0x30

의 연산이 필요하다.

 

실제 x86-64 에서는 아래와 같이 비슷하게 구성된다.


Direct 모드와 Indirect 모드

하나의 명령어에 여러 정보를 담다보면 데이터 크기에 제한이 생긴다.

주소값을 그대로 명령어에 넣게되면, 레지스터의 내 명령어 필드 비트 수에 따라 사용할 수 있는 주소의 범위가 정해진다. 

다만 레지스터의 크기에 비해 사용할 수 있는 주소는 훨씬 넓어야 하기 때문에 메모리를 접근하는 다른 방법이 필요하다.

 

일반적으로 메모리를 그대로 접근해 가져오는 것을 Direct모드 라고 한다.

Direct 모드의 단점을 해결하기 위해 Indirect 모드를 알아보자.

 

Indirect 모드는 메모리를 한 번 우회하여 실제 주소를 참조하는 방식이다.

즉, 0xFFFFFFFF보다 큰 주소에 접근해야 하는 경우, 해당 주소 값을 0xFFFFFFFF 이하의 메모리 공간에 저장해두고,
명령어는 그 저장된 위치를 통해 간접적으로 실제 주소에 접근한다.

이러한 방식에서는 메모리 안에 저장된 주소 값을 먼저 읽고,
그 주소가 가리키는 위치로 접근함으로써 최종 데이터를 얻는다.