본문 바로가기

Language/_Assembly

어셈블리 디자인을 통한 컴퓨터 구조의 접근

1. 레지스터 디자인

고려 사항 : 

레지스터 용량
레지스터 갯수
레지스터 각각의 용도


예)

레지스터 용량 : 16비트,
레지스터 갯수 : r0 ~ r7 (8개)
레지스터 용도 : r0 ~ r3 (저장용),
                      r4(ir : instruction register), r5(sp : stack pointer), r6(lr : link register), r7(pc : program counter)

(참고 : ir 은 다음번에 실행하게 될 명령어를 미리 가져다 놓는 용도로 사용된다)


2. 명령어 구조 디자인

명령어의 구조는 레지스터의 용량, 갯수, 용도에 종속적으로 구성될수 밖에 없다.
(예 : 레지스터가 4개 일때와 8개 일때 명령어 내부에 레지스터를 표현해야할 비트수가 달라진다)

따라서 어셈블리 언어로 구현된 프로그램은 CPU가(레지스터의 구조) 달라진다면 이식을 할수가 없다.


예) 덧셈 명령어 구현

먼저 레지스터 용량이 16비트이므로 명령어도 16비트가 된다.

가장 간단한 구성은 16비트 전체를 덧셈명령어 하나로 채우는 것이다
(1+2=3 를 시키는데 16비트 * 4 를 사용한다)

이렇게 구성하면 비효율적이므로 저장소, 피연산자 2개, 연산자를 하나의 명령어에 담는다.

연산자수는 3비트로 제한한다.(연산자 갯수 : 8개)

 연산자  심볼  2진 코드
 +  ADD  001
 -  SUB  010
 *  MUL  011
 /  DIV  100


저장소에는 레지스터만 올수 있드록 제한하며 3비트만 할당한다.(레지스터 갯수가 8개이므로)

 레지스터 심볼  2진 코드
 r0  000
 r1  001
 r2  010
 r3  011
 r4, ir  100
 r5, sp  101
 r6, lr  110
 r7, pc  111


피연산자에는 숫자와 레지스터가 모두 올수 있으므로 피연산자의 맨 앞의 비트를 할당하여 구별한다.
(0이면 숫자, 1이면 레지스터.       1001 = 레지스터 r1,  0001 = 숫자 1 )

r1 = r2 + 7


어셈블리(Assembly)
: ADD r2, r1, 7

바이너리 코드(Binary Code)
    0     0      0     0     1     0      1    0     1     0     0     1      0     1     1     1


연산의 과정

어셈블리어  ->  바이너리 코드  ->   메모리   ->  I/O 버스  ->  레지스터(ir)  ->  컨트롤 유닛  ->  ALU
              어셈블러            로드(LOAD)     Fetch                                           Decode         Execution


(참고 : RISC , CISC

CISC(Comples Instruction Set Computer, 복잡한 명령어 체계를 가지는 컴퓨터)

: 사용할수 있는 명령어 개수가 많아 프로그램을 구현하는데 편리함을 주고 메모리 길이도 유동적이므로 메모리를
효율적으로 사용할 수 있지만 CPU 는 복잡해지며 성능 향상에 제한이 따른다.

RISC(Reduced Instruction Set Computer)

: CISC 구조가 지니는 명령어(자주 사용하는 명령어는 이중에 10%)를 대폭 줄이고 명령어 길이를 고정시켜 디자인 한 구조. 높은 성능을 내는데 유리하다.(Pipelining라는 기법으로 클럭당 둘이상의 명령어 처리가 가능하다))



3. LOAD & STORE 명령어 디자인 - 메인 메모리와 연동


예)

LOAD = 110,     STORE = 111

LOAD 바이너리 예 : LOAD r3, 0x07)
        1     1      0     0     1     1     0     0     0      0      0      1      1     1 
< -  예약  - > <  --    LOAD  --  > < -  destination  - >  < ------------------- source -------------------- >

STORE 바이너리 예 : STORE r2, 0x08)
        1     1      1      0      1      0       0     0      0     0      1      0      0     0 
< -  예약  - > <  --   STORE --   ><  --- source ---  > <------------------ destination ------------------->



4. Direct 모드와 Indirect 모드

Direct 모드 : 주소값을 명령어에 직접 표현한다.

(참고 : 메모리 주소는 16비트(위의 예에서)인데 반해 명령어에 할당된 주소표현은 8비트이다. 따라서 8비트를 넘어가는 주소표현에서는 문제가 발생한다. 이 문제를 해결하기 위해 Indirect 모드를 사용한다)

Indirect 모드 : 명령어에서 지정하는 번지에 저장된 값을 주소값으로 참조한다.


예)

Indirect 모드연산과 Direct 모드 연산을 구분 하기 위해 비워뒀던 예약의 2비트를 사용한다.

Direct 모드 = 00,           Indirect 모드 = 01



5. 종합

다음을 위에서 만든 어셈블리로 작성해보자.

int a = 10;       //    0x0010 번지 할당  
int b = 20;       //    0x0100번지 할당
int c = 0;         //   0x0020번지 할당

c = a + b;

'Language > _Assembly' 카테고리의 다른 글

함수 호출 과정  (0) 2010.03.06
스택과 콜링컨벤션의 이해  (0) 2009.10.26
상황별 기초 어셈블리어  (3) 2009.10.26
기초 어셈블리어.  (11) 2009.10.25