윈도우즈 시스템 프로그래밍 4장-세션2
시작 전 소개
1챕터 정리본 바로가기
2챕터 정리본 바로가기
3챕터 정리본 바로가기
4챕터 세션1 정리본
LOAD & STORE 명령어 디자인
데이터를 읽어오거나 저장하는 기능과 관련된 명령어를 디자인하는 세션이다.
명령어의 필요성과 디자인
우리가 설계한 레지스터분 아니라 범용적으로 사용되는 RISC구조의 경우 메모리 주소 정보를 사칙연산의 피연산자로 올 수 있도록 구조를 설계하지 않았기 때문에 복잡한 연산이 어려워진다.
바로 이때 필요한 것이 메모리에 store을 하고 그 store한 것을 load하는 과정이다.
LOAD만들기
메인 메모리에 존재하는 데이터를 레지스터로 이동시키는 명령어이다.
우선 LOAD
라는 연산자를 의미하는 2진 코드는 110
으로 지정하였다.
사칙연산과는 달리 우리는 도착지점, 데이터 존재 위치, LOAD를 나타낼 코드만 나타내면 된다.
그렇다면 로드에 3칸을 할당하고, 도착지에도 3칸 할당(기존보다 레지스터의 칸 수가 늘어나지는 않기 때문에) 후 예약 2칸을 사용한 뒤 남은 칸은 모두 저장할 메모리의 주소 정보를 담는 칸으로 두면 된다.
참고로 일반적인 아키텍처에서는 각각 프로세서에 따라 다르지만, 레지스터의 크기가 고정되어 있기 때문에
소스를 표현하는 칸이 저렇게 크게 할당되어있는 것이다.
나는 이것을 몰라서 소스 칸을 왜 아까보다 크게 잡았는가에 대해 고민을 했는데, 레지스터의 크기를 변경하기 위해서는 새로운 프로세서 아키텍처를 설계해야하기 때문에 비용적 시간적 문제가 크다고 한다.
저 디자인한 메모리에 따라 LOAD R3, 0X07
을 표현하려면 최종적으로 이런 코드가 완성된다.
예약:00
Load:110
도착지인 r3:011
정보인 0X07(메인메모리 주소): 0000 0111
총 완성된 코드 디자인:00 110 011 00000111
위 작업에서는 LOAD를 읽은 뒤 컨트롤 타워가 세 개가 아닌 두 개임을 알고 정보를 추출하는 과정을 거치게 된다.
1세션에서 짠 코드의 경우 r2(저장소)와 정보 추출 대상인 r1과 정보(소스)인 7이 오는 반면 LOAD는 도착지와 소스만 오기 때문이다.
STORE 만들기
이번에는 STORE을 통해 레지스터 안에 있는 메모리를 메인 메모리로 이동시키는 작업을 진행할 것이다.
여기서 주의할 점은 load는 메인 메모리의 정보를 레지스터로 옮기는 작업이기 때문에, 도착지를 먼저 할당하였다.
그런데 STORE은 LOAD와 정보의 전달 방향이 반대가 될 수 밖에 없다.
즉 LOAD에서는 Load 도착지(레지스터) 정보(메인 메모리 주소)해석되던 내용이
STORE에서는 똑같은 코드가 디자인되어있어도 해석은 STORE 정보(레지스터) 도착지(메인 메모리 주소)가 되는 것이다.
두개 합치기
현재 변수 a,b,c가 각각 010/020/0*30번지에 들어가있는 상태이다.
우리는 c=a+b
를 연산하기 위해 어떤 작업을 거쳐야 할까?
우선 연산을 진행하기 위해서 a와 b값을 각각 레지스터에 옮기는 작업을 진행하여야한다.
그 이후 1세션에서 진행한 ADD명령어를 실행시키고, 마지막으로 실행된 작업 내용을 STORE을 통해 메인 메모리로 옮기면 된다.
[1단계]변수 A의 내용을 1번 레지스터(R1)에 옮긴다.
00 110 001 00010000
[2단계]변수 B의 내용을 2번 레지스터(R2)에 옮긴다.
00 110 010 00100000
[3단계]ADD를 통해 두 레지스터의 값을 더한다.(3번 레지스터에 저장)
00 001 011 1010 0011
[4단계]STORE를 통해 3번 레지스터에 저장한 값을 c로 옮긴다.
00 111 011 00110000
다이렉트 모드와 인다이렉트 모드
다이렉트 모드
특징: 명령을 수행하는 데에 필요한 위치를 직접적으로 가리킴
할당된 비트수 안에서 표현 가능한 범위의 메모리 영역만 접근이 가능하다.
이러한 단점을 보완하기 위해 나온 것이 바로 인다이렉트 모드다.
인다이렉트 모드
메모리 접근에 다양성을 부여한다.
[]
기호로 감싸서 Indirect연산임을 나타낸다.
위 이미지는 인다이렉트 모드의 접근방식을 표현한 것이다.
보면 레지스터 안에 담긴 150이라는 주소를 통해 메인 메모리의 800주소를 참조한 뒤 1200이라는 데이터를 참조한다.
단점으로는 실행하는 데에 있어서 2번의 메모리 참조가 필요하기 때문에 다이렉트 모드에 비해 느릴 수 있다.
코드 변경
우리가 아까 맨 앞에 두 자리는 예약 공간으로 바이너리 코드 디자인을 할 때 비워놓았다.
바로 그 두자리를 인다이렉트모드/다이렉트 모드 표현에 쓸 예정이다.
11은 인다이렉트 모드
로 00은 다이렉트 모드
이다.
인다이렉트 모드로 문제 해결하기
아까 푼 c=a+b
예제에 0X100
을 참조하라는 조건이 더 붙었다.
0X100
은 2진수로 000100000000
이기 때문에 아까 우리가 설계한 레지스터로는 표현이 불가능하다.
따라서 인다이렉트 모드를 활용하여 0x100(10진수로 256)
을 나타내야 한다.
[1단계]우선 우리는 사칙연산에 0~7값을 사용가능하다.
따라서 256의 약수 중 우리가 사용 가능한 가장 큰 숫자인 4
를 활용한다.
빈 레지스터인 r0에 4라는 값을 집어넣으려면 LOAD를 사용해야한다.
00 011 000 0100 0100
피연산자 두개를 4
로 설정하여 16을 0번 레지스터에 저장하였다.
[2단계]1의 작업을 반복하는데 저장소만 바꾸어준다.
00 011 001 0100 0100
1번 레지스터에 16을 저장한다.
[3단계]이 두 레지스터의 값을 곱하여 256을 만들어준다.
00 011 010 1000 1001
[4단계]위 정보를 메인 메모리에 STORE해준다.
이후 인다이렉트 모드와 load를 활용하여 메인메모리 데이터를 레지스터로 옮길 수 있다.
댓글남기기