- 7
- Hygon
- 조회 수 2155
운영체제를 만들기 위해서는 초반에 어셈블리어를 배워야 합니다. 그런데, 어셈블리어를 작성할 때는 CPU 제조사별로
고려할 사향(레지스터, 어셈블리 문법 등)이 각각 다릅니다. 이 강의에서는 Intel을 기준으로 합니다.
(Intel 과 호환되는 AMD CPU 등에서도 작동합니다.) 따라서 우리가 이번 시간에 배울 16비트 레지스터는
8086 프로세서라는 인텔의 16비트 프로세서를 기준으로 합니다
0. 레지스터의 의미
레지스터가 무엇인지 알려면 메모리 계층에 관해 알 필요가 있습니다.
By Gustlr1222 - 자작, CC BY-SA 3.0, 링크
* 메모리 = RAM 으로 생각하시면 됩니다.
메모리 계층은 위의 그림처럼 속도에 따라 컴퓨터 메모리를 나눈 것으로 생각할 수 있습니다.
이 때 위로 갈 수록 메모리의 크기가 작고 속도가 빠르며, 아래로 갈 수록 크기가 크고 속도가 빠릅니다.
이 그림만 봤을 때 레지스터를 '컴퓨터에서 가장 빠른 메모리'라고 정의할 수도 있겠네요.
이에 설명을 좀 덧붙이자면, CPU에 딸려있는 메모리라고 할 수 있습니다. 컴퓨터의 각각의 부품은
'버스'라는 통로에 의해 연결되는데, 우리가 아는 RAM(Read Access Memory)은 CPU와 버스를 통하지만
레지스터는 CPU내부에 존재하기 때문에 버스를 거치지 않아 더 빠르죠.
그럼 왜 레지스터를 배워야 할까요? 사실 레지스터가 단순히 '가장 빠른 메모리'였다면 굳이 레지스터를 우리가 배울 필요는
없었을겁니다. 왜냐하면 RAM과 레지스터의 차이가 단지 속도 뿐이었다면, 두 메모리를 처리하는 방법은 똑같았을테니까요.
하지만 모든 메모리는 레지스터를 이용해야만 다룰 수 있습니다. 예를 들어, RAM의 0x1000 주소에 있는 int 변수와 0x1004 주소에 있는
int 변수를 '직접' 더할 수 없습니다. 대신에 이를 레지스터라는 공간에 가져와서 더해야 합니다. 따라서 우리는 컴퓨터가 이 레지스터라는 공간을 어떻게 처리하는지 알 필요가 있습니다.
레지스터는 레지스터의 크기에 따라 16비트, 32비트, 64비트로 나눌 수 있습니다. (물론 16비트는 8비트로 다시 나눌 수 있습니다.)
사실은 우리가 32비트 운영체제, 64비트 운영체제라고 하는 것도 레지스터의 크기에 따라 정해집니다.
16비트 운영체제는 요즘 쓰지 않지만 16비트 레지스터를 배워야 하는 이유는 64비트 운영체제를 만들려면(우리는 64비트 운영체제를 만들겁니다.) 16비트 리얼모드 -> 32비트 보호모드 -> 64비트 IA-32e (or Long) 모드로 순서대로 전환을 해야하기 때문입니다. 사실 16, 32, 64비트를 한꺼번에 다룰까 했지만 지루해질 수 있어, 차례대로, 필요할 때 마다 다루려고 합니다.
자, 레지스터에 관해 설명을 장황하게 한 것 같습니다. 이제 16비트 레지스터가 어떻게 생겨먹었는지 알아봅시다.
레지스터는 크게 다음의 세 가지로 나눌 수 있습니다.
1. 범용 (General) 레지스터
2. 세그먼트 레지스터
3. 플래그 레지스터
1. 범용 레지스터
범용(다목적) 레지스터는 다시 세부적으로 다음과 같이 나눌 수 있습니다.
1.1 데이터 레지스터 : 수학 or 논리적 연산에 사용되는 레지스터
- AX (Accumulator Register, 연산 레지스터) :
CPU 가 많이 쓰는 변수 중 하나, 주로 사칙연산을 하고,
함수에서 리턴을 할 때 리턴 값을 담아서 전달하기도 한다.
- BX (Base Register, 기본 레지스터):
특별한 목적이 있는게 아닌, 다용도로 사용되는 레지스터이다.
- CX (Count Register, 카운트 레지스터) :
이름의 Count 처럼 반복문 등을 할 때 보통 횟수를 지정하면서 작동하는데
그 수를 셀 때 사용하는 레지스터이다. 카운트를 할 필요가 없을땐 EBX 처럼
다용도로 사용된다.
- DX (Data Register, 데이터 레지스터) :
AX 나 BX 처럼 연산을 하거나 범용으로 쓰인다.
* 각각의 데이터 레지스터는 다음과 같이 사용할 수 있다.
AX : 16비트 전체
AH : 상위 8비트
AL : 하위 8비트
(AX, AH, AL에서 A만 B,C,D로 바꾸면 BX, CX, DX 에 대해서도 똑같이 사용할 수 있습니다.)
1.2 포인터 레지스터
- IP (Insturction Pointer) : 다음에 실행될 명령어의 주소를 저장하는 포인터로, 주소 자체가 저장되는 것이 아니라
코드 세그먼트에 대한 오프셋이 저장된다. (코드 세그먼트는 곧 배웁니다.)
- SP (Stack Pointer) : 일반적으로 스택 세그먼트에대한 오프셋으로 사용되며, 스택의 가장 윗 부분을 가리킨다.
- BP (Base Pointer) : 일반적으로 스택 세그먼트에 대한 오프셋으로 사용되며, 스택의 가장 아랫 부분을 가리킨다.
1.3 인덱스 레지스터
- SI (Source Index) : 문자열 연산에서, 출발지 주소에 대한 인덱스로 사용됩니다. 원래 영어로는 이를 source라고 표현하는데,
쉽게 말해 A라는 문자열을 B라는 주소에 복사할 때, A는 '복사할'문자열 이므로 source, 즉 출발지이고, B는 '복사될'주소이므로
destination, 즉 도착지가 됩니다.
- DI (Destination Index) : 문자열 연산에서, 도착지 주소에 대한 인덱스로 사용됩니다.
이렇게 범용 레지스터는 AX, BX, CX, DX, SP, BP, SI, DI 여덟 개가 있습니다.
2. 세그먼트 레지스터
세그먼트는 메모리의 주소 영역을 분할하는 단위를 말합니다. 16비트에서는 단순히 주소 영역을 나누는 기능만 수행합니다.
16비트 리얼모드에서는 최대 1MB(대략)의 메모리 영역에 접근할 수 있는데, 레지스터의 크기 만큼의 주소만 접근이 가능하므로
2^16 = 64KB 크기의 주소 영역에만 접근을 할 수 있어야 할텐데 어떻게 1MB까지 접근이 가능할까요? 이유는 바로 세그먼트 레지스터를 이용하기 때문입니다. 물론 세그먼트 레지스터도 16비트이지만, (16비트 세그먼트 레지스터) * 16 + (4비트 오프셋) 이라는 계산 방법을 통해주소 공간을 20비트로 늘릴 수 있고, 따라서 약 1MB크기의 주소 영역에 접근할 수 있습니다. (이런 접근 방법은 16비트 리얼모드에서만 사용됩니다. 운영모드별 차이에 주의하세요!)
세그먼트 레지스터는 다음과 같은 종류가 있습니다.
- CS (Code Segment) : 실행할 코드가 담긴 주소 영역의 시작 가리키는 세그먼트 레지스터
- DS (Data Segment) : 데이터가 담긴 주소 영역의 시작을 가리키는 세그먼트 레지스터
- SS (Stack Segment) : 스택의 주소를 가리키는 세그먼트 레지스터
- FS, GS, ES : 용도가 딱히 정해지지 않은 세그먼트 레지스터
3. 플래그 레지스터
플래그 레지스터는 CPU에서 연산 결과를 알려주는 비트들이 모인 레지스터 입니다. 다음과 같은 플래그들이 있습니다.
(전부 외우려 하지 마시고 필요할 때 보세요!!)
플래그 기호 | 이름 | 의미 |
O | 오버플로 플래그 | 부호 있는 숫자의 연산 결과가 비트 범위를 넘어섰을 때 참이 된다. |
D | 디렉션 플래그 | 문자열 조작에서 참일 경우 주소 레지스터 값이 자동으로 감소하고, 거짓일 경우 자동으로 증가한다. |
I | 인터럽트 플래그 | 이 플래그가 참일 경우에만 인터럽트 요구를 받아들인다. 일반적으로 관리자 모드에서만 값을 변경할 수 있다. |
T | 트랩 플래그 | 참일 경우 한 명령이 실행할 때마다 인터럽트가 발생한다. 디버깅에 사용된다. |
S | 사인 플래그 | 연산 결과가 음수일 때 참이 된다. |
Z | 제로 플래그 | 연산 결과가 0일 경우에 참이 된다. |
A | 보조 캐리 플래그 | 연산 결과 하위 니블(4bits)에서 연산 결과가 비트 범위를 넘어섰을 때 참이 된다. 이진화 십진법(BCD)에 사용된다. |
P | 패리티 플래그 | 연산 결과에서 1로된 비트의 수가 짝수일 경우 참이 된다. |
C | 캐리 플래그 | 부호 없는 숫자의 연산 결과가 비트 범위를 넘어섰을 때 참이 된다. |
출처 - 위키백과
참고문헌
https://www.tutorialspoint.com/assembly_programming/assembly_registers.htm
https://wiki.skullsecurity.org/index.php?title=Registers
https://eclass.upatras.gr/modules/document/file.php/EE649/8086%20Registers.htm
이번 시간에 배운 것
1. 레지스터의 의미, 메모리 계층 구조
2. 범용 레지스터 - EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI
3. 세그먼트 레지스터 - CS, DS, SS, ES, FS, GS
4. 플래그 레지스터
연습문제
1. 메모리에 각각 다음과 같은 변수가 있다고 하자.
int a = 10;
int b = 9;
아래의 연산에 레지스터가 필요한 이유를 서술하시오.
a + b
2. 16비트 리얼모드에서 세그먼트 레지스터를 이용한 주소 접근 방식에 대해 서술하시오.
3. 메모리 계층 구조를 종이에 한 번 그려시오.
4. AX에 0110 1100 1010 1101 이라는 16비트 값이 들어있다고 하자, 여기서 AH, AL의 값은 각각 무엇인가?
추천인 1
작성자
댓글 7
.
그래도 몇 번 보니까 이해는 되더라구요 :)
품질 좋은 강좌 감사합니다 :)
몇 가지 제안이 있습니다.
먼저 중간에 오타로 보이는 내용이 있었습니다.
https://wiki.osdev.org/Expanded_Main_Page
그리고 OSDev Wiki에 있는 내용은 위키 피디아가 아닌 OS Dev Wiki 쪽으로도 걸어두시면 보시는 분들에게 더 좋은 참고 자료가 되지 않을까 싶어요!
강좌 기대하겠습니다아~