2012년 8월 24일 금요일

윈도우즈 시스템 프로그래밍 [4] - 컴퓨터 구조 2



윈도우즈 시스템 프로그래밍을 공부하면서 정리한 글입니다.



4장. 컴퓨터 구조 2



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



1. 컴퓨터를 디자인 하자


- CPU의 기본 요소 : ALU, Control Unit, Registers
- 이중 register 만을 디자인 대상으로 삼음
- 시스템 프로그래머(어셈블리 프로그래머)가 CPU를 볼 때 register에 초점을 둠


2. 레지스터를 디자인하자


① 몇 비트로 구성?    16비트
② 몇 개의 레지스터로 구성?    8개 (r0 ~ r7)
③ 레지스터 각각의 용도?









- ir : instruction register

- sp : stack pointer

- lr : link register 

- pc : program counter




3. 명령어 구조를 디자인 하자


- CPU 구성 형태 ( 레지스터 구성 형태 )에 따라 명령어 구조가 달라짐

∴ 레지스터를 디자인 한 후 명령어를 디자인 함.

- 어셈블리어로 구현된 프로그램은 구조가 다른 CPU로 인식이 불가능
- 16비트를 최대한 효율적으로 활용할 수 있도록 구성
   2^16 = 65536개
   C / C++ 연산자 = 100개를 넘지 않음

ex) 레지스터 r1에 있는 값과 7을 더해 r2에 저장하라

=> 총 4개의 정보 필요 : "덧셈", "레지스터 r1", "레지스터 r2", "숫자 7"


- 연산자 :

덧셈  :  ADD,  001
뺄셈  :  SUB,  010
곱셈  :  MUL,  011
나눗셈  :   DIV,  100

- 저장소 : 레지스터가 8개 이므로 3비트 할당

- 피연산자 1, 2 : 숫자가 들어갈 수 있도록 디자인

- 피연산자 부분 -> 저장된 데이터가 숫자인지 레지스터인지 구분이 어려움
  => ∴ 네개의 비트 중 첫번째 비트가 1이면 레지스터 정보를 나타냄

ex) 1001 : r1,  0001 : 숫자 1

but 숫자를 8개 밖에 표현하지 못하는 제약 사항이 있음


- 명령어는 ir (instruction resiter )에 저장됨
   => 다음번 실행될 명령어를 미리 가져다 놓는 용도

- 구성하는 명령어의 형태에 따라 Control Unit ( 명령어를 해석하는 역할 ) 의 구조가 결정됨

- 여러가지 제약 사항들은 CPU의 종합적 성능이 고려되는 가운데 등장하게 됨
   ex) 첫번째 피연산자 위치에는 레지스터 이름만 와야함


① CISC 구조 (Complex Istruction Set Computer)

-  복잡한 명령어 체계를 가지는 컴퓨터
- 다양한 명령어를 제공 -> 수십줄에 걸쳐 구현해야할 명령어를 단 한줄로 구성할 수 있음
- 메모리를 효율적으로 사용할 수 있음
   but CPU구조가 복잡해져야 함 => 성능 향상에 제한


② RISC 구조 (Reduced Instruction Set Computer)

- CISC 구조에서 10%의 명령어만 주로 사용됨에 착안
- 명령어 수를 줄이고 길이를 일정하게 디자인
- 근래 CPU, 임베디드 환경에서 사용되는 대부분의 CPU
   => 클럭당 처리하는 명령어 수를 늘여줌 ( Pipelining ) => 성능 향상 ( 물론 초당 클럭수도 중요 )




II. LOAD & STORE 명령어 디자인



1. LOAD & STORE 명령어의 필요성


- 지금까진 " 사칙 연산 결과를 레지스터에만 저장할 수 있다 "는 제약을 둠
   => ∴ 피연산자에 메모리 주소를 사용할 수 없음


2. LOAD & STORE 명령어의 디자인




- 이전에 디자인 한 사칙 연산에 비해 피연산자가 두개(메인 메모리, 레지스터) 만 필요
- LOAD -> 110

ex) Load r3, 0x07
|  00  |  110  |  011  |  00000111  |

- STORE -> 111   // destination 과 source가 반대


ex) "c = a + b"

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






III. Direct 모드와 Indirect 모드



1. Direct 모드의 문제점과 Indirect 모드의 제안


- 하나의 명령어에 여러 정보를 담음 -> 데이터 크기의 제한

ex) destination에는 레지스터가 8개나 되므로 문제가 없으나
source 부분에는 0x0000 ~ 0x00ff까지만 표현할 수 있음

- Direct 모드 : 할당된 비트 수 만큼의 메모리 영역만 접근 가능  =>  주소값을 명령어에 '직접' 표현




2. Indirect 모드의 이해


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




3. Indirect 모드의 활용 예제


ex)

   int a = 10;   // 0x0010번지에 할당
   int b = 20;   // 0x0100번지에 할당 => Direct 모드로는 불가능
   int c = 0;      // 0x0020번지에 할당
   c = a + b;


=====================

LOAD r1, 0x0010
MUL r0, 4, 4
MUL r2, 4, 4
MUL r3, r0, r2

STORE r3, 0x0030
(LOAD r2, r3는 사용 불가능 => source 부분에는 주소 정보만 사용가능 하기 때문)

LOAD r2, [0x0030]    // 0x0030에는 0x0100이 저장되어 있음

ADD r3, r1, r2




참고 : 뇌를 자극하는 윈도우즈 시스템 프로그래밍. 윤성우 저



댓글 없음:

댓글 쓰기