3장. 일반적인 개념들

 

3.1. 프로그램이 OS상에서 실행되는 순서 (메모리 탑재, 프로세스 실행)
컴퓨터 운영체제에 프로그램을 탑재하고 실행하면, 다음과 같은 순서로 일이 진행 된다.

1) 사용자는 특정 프로그램을 실행하는 명령어를 입력한다. 혹은 프로그램 아이콘을 클릭한다.
2) 운영체제는 현재 디렉토리에서 프로그램의 파일명을 찾는다. 만약 찾지 못하면 Path로 지정해놓은 프
로그램 목록에서 프로그램의 파일명을 찾는다. 프로그램 목록에서도 못찾으면 운영체제는 에러 메시지를
발생시킨다.
3) 프로그램의 파일명을 찾았다면, 디렉토리로부터 파일의 크기, 하드 디스크내에 프로그램의 물리적인
위치등 파일에 대한 기본적인 정보를 추출한다.
4) 운영체제는 사용 가능한 메모리 공간을 찾아 그 프로그램의 파일을 메모리에 탑재한다. 운영체제는
그 프로그램을 위해 메모리의 특정한 블록을 할당하고 프로그램의 크기나, 위치 등에 대한 정보를
Descriptor Table에 저장시킨다.
5) 운영체제는 중앙처리장치가 해당 프로그램의 첫 기계어를 실행 하도록 분기 명령어를 실행한다. 그
프로그램이 실행되면 그것을 프로세스(Process)라고 부른다. 운영체제는 그 프로세스에게 실행 되는 동
안에는 프로세서ID라는 식별 번호를 부여한다. 이는 프로세스를 추적을 가능하게 한다.
6) 프로세스는 스스로 실행 되며, 그 프로세스를 추적하고, 시스템 자원의 요구(메모리, 디스크 파일,
입출력 장치등)를 받는 것은 운영체제의 몫이다.
7) 해당 프로세스가 종료되면, 핸들은 제거 되고 사용되던 메모리는 다른 프로그램을 위해 해제 된다.

 

3.2. 마지막으로.

 2장에서 공부한 80386에서 현재 나온 최신 CPU인 인텔 듀오2 CPU까지를 통틀어서 모든 32비트 CPU를 IA-32 프로세서라고 한다. 비록 프로세서 성능과 기능면에선 비교할 수 없을 만큼 많은 발전이 있었지만, 이러한 것은 IA-32 표준 뒤에 숨겨져 있다. 프로그래머의 입장에서 보면 IA-32 구조는 80386이후로 실질적으로 바뀐것이 거의 없다. 예외가 있다면 멀티미디어 처리를 위한 고성능 명령어들이 추가 되었다는 것이다. 이런 이유로 80386의 구조는 매우 중요하다. 때문에 80386 프로세서의 내용이 이해가 잘 가지 않는다면 다시 한번 꼼꼼히 참고 하여 보기 바란다. 인터넷에서도 이에 대한 많은 자료를 찾을 수 있고, 친절하게 인텔 메뉴얼 까지 존재한다. (인텔 CPU를 공부 하기 위해서는 이 메뉴얼은 필수 적이다. Intel 홈페이지에서 찾으면 무료로 PDF 파일을 다운로드 받을 수 있다.)

 


'80x86 프로세서' 카테고리의 다른 글

2장. 80386 프로세서 (3/3)  (0) 2010.04.12
2장. 80386 프로세서 (2/3)  (0) 2010.04.12
2장. 80386 프로세서 (1/3)  (0) 2010.04.12
1장. 8086/8088 프로세서 (2/2)  (2) 2010.04.12
1장. 8086/8088 프로세서 (1/2)  (3) 2010.04.12

2장. 80386 프로세서 (3/3) 


2.5. 보호모드

 보호 모드의 특징은 새로운 주소 지정 메커니즘과 보호 수준이다. 새로운 주소 지정 방식에는 세그먼테이션 방식과 페이징이 사용되며, 이는 가상 메모리(virtual memory)지원 하게 된다. 가상 메모리란, 프로세서가 무제한의 물리 메모리를 가지고 있다고 생각하도록 만드는 기술이다. 두 방법 모두 필요에 따라 하드디스크와 사용자 메모리 블록을 교체(swapping)한다.

 보호 모드의 마지막 특징은 개별 프로그램(Task)에 특권 수준(Privilege level)을 부여하는 기능이다. 하위 특권 수준의 프로그램은 상위 특권 수준의 프로그램을 엑세스 할 수 없다. 실제로 운영체제가 가장 높은 특권 수준을, 주로 사용자가 사용하는 응용프로그램에 가장 낮은 특권 수준이 부여 되어 운영체제를 엑세스 할 수 없게 만든다. (물론 게이트란 특별한 형태의 디스크립터로 낮은 특권 수준의 프로그램이 높은 특권 수준의 데이터나 다른 프로그램을 엑세스 할 수 있게 한다.)



2.5.1. 세그먼테이션

 실제 모드와 마찬가지로 보호모드에서도 세그먼트가 존재한다. 하지만 각 세그먼트의 크기는 1바이트에서 4GB(386의 전체 주소 공간 크기)까지 가변적이다. (실제 모드에서의 세그먼트의 크기는 64KB(2의16승)로 고정되어있다.) 그리고 보호모드의 세그먼트 레지스터는 바로 세그먼트의 시작주소를 가리키지 않고  디스크립터 테이블(Descriptor table)을 가리키는 포인터(Pointer)로 사용된다. 386의 메모리 세그먼트는 보호모드에서 동작할 때가 실제 모드에서 동작할 때 보다 유연성이 크다.



보호모드 메모리 세그먼트의 특징

1) 고정된 64KB의 크기 대신 1바이트에서 부터 4GB까지 원하는 크기를 가질 수 있다.

2) 각 메모리 세그먼트에는 보호수준이 부여된다.(하위 보호수준으로 동작하는 프로그램은 상위 보호수준의 세그먼트를 엑세스할 수 없다.)

3) 16,384개의 서로 다른 세그먼트를 정의할 수 있다. (GDT, LDT 포함)

4) 곧바로 디스크로 교체되어 나갈 수 있어, 가상 메모리를 지원한다. (선택된 세그먼트가 메모리에 있는지, 디스크에있는지는 상태 비트를 통해 알 수있다.)

5) 세그먼트는 코드와 데이터 보호를 위해 읽기전용(read-only)로 설정할 수 있다.



용어 정리

1) 셀렉터(Selector)

 보호모드에서는 세그먼트 레지스터가 디스크립터 테이블을 선택하기 때문에 셀렉터라고 부른다.


2) 디스크립터(Descriptor)

 디스크립터의 크기는 8바이트이다. 이 8바이트를 사용하여 해당 세그먼트의 시작주소, 세그먼트의 크기(한계), 세그먼트의 속성들을 설정한다. 하나의 디스크립터당 하나의 물리주소의 세그먼트를 가지고 있다.


3) 디스크립터 테이블(Descript table)

 이런 디스크립터들이 여러개 모인 것을 디스크립터 테이블이라고 한다.(386에는 GDT, LDT, IDT 3종류의 디스크립터 테이블이있다.)


4) 특권 수준(Privilege Level) 

 4단계의 특권 레벨이 존재한다. Level 0이 가장 특권 레벨이 높고, Level 3이 가장 낮다. 레벨의 숫자가 클 수록 특권 수준은 낮다. 특권 수준이 낮으면 높은 특권 수준의 태스크에 접근 할 수 가 없다.



셀렉터와 디스크립터

 보호 모드 메모리 세그먼트를 지정하기 위해서는 세그먼트의 시작주소, 크기, 속성을 알아야 한다. 하지만 16비트 세그먼트 레지스터는 이러한 목적으로 사용하기엔 그 크기가 충분치 않다. 그렇기 때문에 보호모드에서의 세그먼트 레지스터는 디스크립터를 선택하는데 사용된다. 이 선택된 디스크립터 안에 세그먼트의 시작주소, 크기, 속성들이 저장되어 있다.



디스크립터 테이블(Descriptor Tables)
 디스크립터 테이블은 전역 디스크립터 테이블(Global Descriptor Table), 지역 디스크립터 테이블(Local Descriptor Table) 그리고 인터럽트 디스크립터 테이블(Interrupt Descriptor Table)이 존재한다. 모든 디스크립터 테이블들은 가변 길이 메모리 배열이다.(정의된 세그먼트에 따라 테이블의 크기가 가변적이다.) 이 테이블들은 8바이트에서 64KB까지의 크기를 가질 수 있다. 각 테이블은 8,192개의 8바이트 크기를 가진 디스크립터들을 가질 수 있다.



3종류의 디스크립터 테이블

1) 전역 디스크립터 테이블 (GDT, Global Descriptor Table)

 이 디스크립터 테이블의 항목은 시스템의 모든 태스크가 사용할 수 있는 세그먼트들을 기술한다.


2) 지역 디스크립터 테이블 (LDT, Local Descriptor Table) 

 이 디스크립터 테이블의 항목은 주어진 태스크와 관련된 세그먼트를 기술한다. 각 태스크는 별도의 LDT를 가질 수 있다.


3) 인터럽트 디스크립터 테이블 (IDT, Interrupt Descriptor Table)

 이 디스크립터 테이블의 항목은 최고 256개의 서로 다른 인터럽트 서비스 루틴의 시작 주소를 가리킨다.



디스크립터(Descriptor)

 세그먼트의 인덱스가 가리키는 곳을 디스크립터라고 부른다. 디스크립터의 크기는 8바이트이며 이 안에 선형 주소의 블럭에 대한 속성들이 저장되어 있다. 디스크립터는 크게 가리키는 세그먼트의 시작주소(base address), 세그먼트의 크기(한계), 그리고 기타 속성들로 나누워 진다. [그림 2-5-1-1]은 디스크립터의 구성이다.


1) 세그먼트의 시작 주소

Segment Base Address 31~24 비트 (byte 7)

Segment Base Address 23~16 비트 (byte 4)

Segment Base Address 15~ 8 비트 (byte 3)

Segment Base Address   7~ 0 비트 (byte 2)


2) 세그먼트의 크기

Segment Size Limit 19~16 비트(byte 6)

Segment Size Limit 15~8 비트 (byte 1)

Segment Size Limit 7~0 비트(byte 0)


[그림 2-5-1-1] 디스크립터 비트 구성




세그먼트 레지스터(셀렉터)의 구성

 [그림 2-5-1-2]을 참고하면서 설명을 듣자.

세그먼트 레지스터의 2번 비트 가 0일 경우 GDT(Global Descriptor Table)이고, 1일 경우에 LDT(Local Descriptor Table)을 가리킨다. 가리킬 디스크립터 테이블의 인덱스 번호(디스크립터 번호)는 상위 13비트(15~3)를 가지고 결정한다. 총 2의 13(8,192)개의 디스크립터 테이블 인덱스가 존재 한다. 이 상위 13비트로 디스크립터를 선택할 때 디스크립터 테이블의 시작 주소가 저장되어있는 GDTR이나 LDTR과 더한다. (디스크립터 테이블의 시작 주소에 인덱스 번호를 더하면 해당 디스크립터의 시작 주소를 가리킨다. [그림 2-5-1-2] 참고) 마지막으로 하위 2비트(0,1 번째 비트)들은 요청할 특권 수준(RPL, Requestor Privilege Level)을 말한다.


[그림 2-5-1-2] 세그먼트 레지스터 비트 구성

 


세그먼테이션 4단계

1) 세그먼트 레지스터의 두번 째 비트가 0이면 전역 디스크립터 테이블, 1이면 지역 디스크립터 테이블을 가리킨다.


2) 세그먼트 레지스터의 상위 13비트를 시스템 GDTR 또는 LDTR에 더하여 특정 디스크립터를 선택한다. ([그림 2-5-1-2] 참조)


3) 세그먼트 레지스터의 0,1번 비트의 특권 수준이 디스크립터의 특권수준(DPL, [그림 2-5-1-1]의 byte 5에 있는 DPL 참조)과 비교하여 낮으면 Fault(인터럽트)를 일으킨다. (접근할려고 하는 세그먼트 보다 특권 수준이 낮으면 접근 불가)


4) 요청된 특권 수준이 디스크립터의 특권 수준과 같거나 높으면 세그먼트의 32비트 시작 주소([그림 2-5-1-1]의 byte 2, 3, 4, 7 Segment Base Address 참조)에 32비트 offset을 더하여 엑세스할 데이터의 32비트 물리 주소를 얻는다. ([그림 2-5-1-3]  참조)


[그림 2-5-1-3] 세그먼테이션 과정

 



2.5.2. 페이징

 세그먼테이션은 메모리 단편화라는 단점이 있다. 메모리 단편화는 컴퓨터가 가변 길이의 메모리 세그먼트를 관리하려할 때 발생한다. (인터넷에서 메모리 단편화 라고 검색해보자. 자세한 설명이 많이 나온다.) 이 단점을 극복하기 위해 페이징 방식을 도입 하였는데, 이는 가용 메모리 공간을 4KB의 동일한 블럭(페이지)로 나눔으로써 메모리 단편화를 막을 수 있다. 이 페이지는 비교적 크기가 작고 동일한 크기를 가지므로 OS는 좀더 효율적으로 사용 할 수 있다. 고정길이의 페이지가 가변 길이의 세그먼트보다 관리하기가 쉬우므로 OS가 빠르게 반응한다.

 페이징 방식은 제어레지스터 CR0의 31번째 비트를 1로 셋 시키면 enable 되며, 32비트의 선형 주소를 별도의 페이지 디렉토리 표(Page Directory Table)와 페이지 변환표(Page Translation Table 또는 Page Table)를 통하여 4KB 페이지 프레임 내의 새로운 물리주소를 계산하게 한다. ([그림 2-5-2-1]을 참고하자.)



주소변환의 3단계 

[그림 2-5-2-1]을 참고 하면서 읽어 나가자.

1) 선형 주소의 상위 10비트(Dir)을 오프셋으로 하여, CR3 레지스터(페이지 디렉토리의 시작주소를 가지고 있다.)의 주소와 더해져 해당 페이지 디렉토리의 항목을 정한다. 해당 페이지 디렉토리 항목엔 페이지 변환표의 시작 주소가 들어있다. (페이지 디렉토리 각 항목은 해당 페이지 변환표를 가리키고 있다.)


2) 선형 주소의 중간 10비트(Table)는 Dir에서 지정된 페이지 디렉토리의 항목과 더해져 해당 페이지 변환표의 항목을 정한다. 이 항목엔 물리 메모리에서 나누워진 어떤 4KB 블럭의 시작 주소를 가지고 있다.


3) 페이지 변환표에서 얻은 4KB의 시작 주소에 선형 주소의 Offset 부분을 더해 물리 주소를 구하게 된다.


[그림 2-5-2-1] 페이징 

 



2.5.3. 세그먼테이션과 페이징의 혼합

 세그먼테이션방식과 페이징의 혼합된 방식이다. 실제 이 방식으로 구현이 되어있으며, 페이징 기능을 사용하지 않을 때(CR0 레지스터의 31번째 비트가 0일 경우)는 세그먼테이션으로 나온 프로세서의 선형 공간이 프로세서의 물리 주소 공간으로 바로 매핑(mapping)된다. 페이징 기능을 사용할 경우엔 세그먼테이션으로 얻어진 선형 주소가 페이징 방식에 필요한 32비트 선형 주소가 된다. 그 이후 변환과정은 앞에서 설명한 페이징 방식과 동일하다.


[그림 2-5-2-2] 세그먼테이션 과 페이징




2.5.4. 특권 규칙 

 멀티 태스킹 OS에서는 실행되는 프로그램은 절대로 특권이 높은 데이터나 프로그램(태스크, Task)을 엑세스해서는 안된다. 그렇지 않으면 운영체제를 포함한 다름 모든 태스크들을 다운시킬 수 있다. 386은 3가지 특권 수준(PL : Privilege Level)을 제공하는데 0(2진수 00)에서 3(2진수 11)까지 있다. 낮은 특권 수준은 주로 사용자의 응용 프로그램에 부여되며, 높은 특권 수준은 OS의 커널에 부여된다. 사용되는 경우는 세그먼테이션 4단계에서 설명 했다.

'80x86 프로세서' 카테고리의 다른 글

3장. 일반적인 개념들  (0) 2010.04.12
2장. 80386 프로세서 (2/3)  (0) 2010.04.12
2장. 80386 프로세서 (1/3)  (0) 2010.04.12
1장. 8086/8088 프로세서 (2/2)  (2) 2010.04.12
1장. 8086/8088 프로세서 (1/2)  (3) 2010.04.12

2장. 80386 프로세서 (2/3) 

2.4. 레지스터

 1장에서 말했듯이 레지스터란 중앙처리장치 내부에 있는 고속의 저장장치로서 메모리보다 빠른 엑세스를 위해 설계되었다. 80386의 레지스터는 8개의 범용 레지스터, 6개의 세그먼트 레지스터(8086에서난 4개의 세그먼트레지스터가 있다.), 그리고 상태 플래그와 명령어 포인터를 가지고 있다. 이 레지스터들은 이전 CPU(8086, 80286등..)들의 레지스터들을 다 포함 한다.(하위 호환성 유지)

 

[그림 2-4-1] 범용 레지스터, 세그먼트 레지스터, 명령어 포인터, 상태 플래그 레지스터

 

 

범용 레지스터

 범용 레지스터는 계산과 데이터 이동에 주로 사용된다. 이 레지스터들은 [그림 2-4-2]에서 보는 것처럼 하나의 32비트 값 혹은 16비트, 8비트 값으로 처리 될 수 있다.

예를들어 범용 레지스터인 EAX는 32비트 레지스터 이고, AX는 16비트, AH(상위비트),AL(하위비트) 은 8비트 레지스터이다.

 

[그림 2-4-2] 32비트, 16비트, 8비트 범용레지스터, 32비트 명령어 레지스터, 16비트 명령어 레지스터

 

[표 2-4-1] 32,16,8비트로 사용할 수있는 레지스터

32비트

16비트

8비트(상위)

8비트(하위)

EAX AX AH AL
EBX BX BH BL
ECX CX CH CL
EDX DX DH DL
EAX : 곱셈과 나누셈 명령에서 자동으로 사용된다. 확장된 누산기(EAX, extended accumulator)레지스터 라고 부른다.
ECX : 루프 카운터로 사용된다.
 

[표 2-4-2] 32비트, 16비트 인덱스,포인터 레지스터

32비트

16비트

ESI SI
EDI DI
EBP BP
ESP SP
ESI(Extended Source Index) : 고속 메모리 전송 명령에 사용된다.
EDI(Extended Destination Index) : 고속 메모리 전송 명령에 사용된다.
EBP(Extended Base Pointer) : 고급언어에서 스택 상에 있는 지역 변수와 함수 매개변수를 참조하기 위해 사용된다. 일반적인 계산이나 데이터 이동을 위해 사용해서는 안된다.
ESP(Extended Stack Pointer) : 스택에 있는 데이터를 가리킨다. 이 레지스터는 일반 적인 계산이나 데이터 이동을 위해 절대로 사용 될 수 없다.
[표 2-4-2]에서의 16비트 레지스터들은 80386의 실제모드(real mode)에서 수행되는 프로그램 작성시에만 사용된다.
 
 
명령어 레지스터(IP, Instruction Point)
명령어 포인터(IP)의 32비트 레지스터 이름은 EIP이다. 명령어 포인터는 바로 다음에 실행할 명령어 주소의 오프셋이 들어 있다. 이 오프셋(EIP)은 항상 코드 세그먼트(CS)와 결합된다. EIP의 하위 16비트는 IP이다. 이 16비트 레지스터는 실제 모드에서 사용된다.
 
[표 2-4-3] 32비트, 16비트 명령어 포인터 레지스터

32비트

16비트

EIP IP
 
 
세그먼트 레지스터
 80386의 세그먼트 레지스터는 실제모드에서 8086과 동일한 기능을 한다. 하지만 보호모드에서는 새로운 주소 지정방식이 사용된다. 세그먼트 레지스터가 여전히 유지 되지만, 각 세그먼트의 크기는 1바이트에서 4GB까지의 크기를 가질 수 있다. 이 때 세그먼트 레지스터에 저장된 주소는 [그림 2-4-3]처럼 디스크립터 테이블(descriptor table)을 가리키는 포인터로 해석된다. 자세한건 보호모드에서 알아 보도록 하자.
 
[그림 2-4-3] 디스크립터 레지스터를 선택하고 있는 세그먼트 레지스터
 
플래그 레지스터
 플래그 레지스터도 80386으로 넘어오면서 32비트로 확장 되었다. 8086의 상태 및 제어 플래그가 그대로 유지 되었지만, [그림 2-4-4]에서 보는 것 처럼 4개의 플래그가 새롭게 추가 되었다.
VM(Virtual 8086 Mode) : 가상모드. 이 플래그는 프로세서를 가상 8086모드로 전환하는데 사용되는 보호 모드 제어 플래그이다.
RF(Resume Flag) : 재개 프래그. 디버그 레지스터와 함께 사용 된다. set되면 디버그 고장은 무시되고 다음 명령어가 정상적으로 사용된다.
NT(Nested Task Flag) : 내포 태스크. 보호 모드에서 현재 태스크가 다른 태스크에 의해 호출되었음을 나타내는 데 사용된다. 이는 내포된 태스크가 끝났을 때 실행될 반환(return) 명령어의 형태에 영향을 미친다.
IOPL(Input/Output Privilege Level) : 입출력 특권 수준. 이 두 개의 보호모드 제어 비트는 I/O명령어를 실행하는 데 필요한 현재 특권수준(0-3)을 나타낸다. 이에 따라 운영체제는 태스크의 I/O특권을 제어한다.
 
[그림 2-4-4] 플래그 레지스터
 
 
제어 레지스터
 이 레지스터들은 보호 모드에서 프로세서 제어와 검사를 위한 목적을 가지고 있으므로 정상적으로는 응용 프로그래머는 사용하지 않는다.
 
CR0 : 페이징 메커니즘의 활성화, 태스크 전환의 감시, 보조프로세서 에뮬레이션의 인에이블, 보호 모드와 실제 모드 동작의 선택에 사용된다.
CR2 : Page fault를 일으킨 마지막 명령어의 주소를 가지고 있다. Page fault란 메모리에 있지 않은 페이지나 세그먼트에 대한 참조를 말한다. page fault가 일어나면 해당 페이지를 디스크에서 가져와 메모리에 적재 하여야한다.
CR3 : 페이징을 통한 가상 메모리가 인에이블 되었을 때 사용된다. 이 레지스터는 페이지 디렉토리의 시작 주소를 가지고 있다. 이 항목은 페이지 변환 표라고 하는 표에 들어있는 항목의 위치를 찾는 데 사용된다. 페이지 변환 표란 4KB 크기의 페이지 프레임의 물리적 시작 주소와 그 프레임에 대한 엑세스 정보를 가지고 있는 표이다.
 
[그림 2-4-5] CR0 레지스터

 

[그림 2-4-6] CR2, CR3 레지스터

 

시스템 주소 레지스터

 보호 모드에서 사용되는 디스크립터 테이블에 대한 정보를 저장하기 위해 제공되는 레지스터이다. (GDTR, ITDR, TR, LDTR -> 4개가 제공된다.) 자세한건 보호모드에서 알아 보도록 하자.

 

[그림 2-4-7] 시스템 주소 레지스터


'80x86 프로세서' 카테고리의 다른 글

3장. 일반적인 개념들  (0) 2010.04.12
2장. 80386 프로세서 (3/3)  (0) 2010.04.12
2장. 80386 프로세서 (1/3)  (0) 2010.04.12
1장. 8086/8088 프로세서 (2/2)  (2) 2010.04.12
1장. 8086/8088 프로세서 (1/2)  (3) 2010.04.12

2장. 80386 프로세서 (1/3) 

 

2.1. 개요

 8086/88의 후속작은 보호모드를 최초로 지원하는 CPU 80286이다. 이때 당시 MS-DOS가 주로 사용되었기 때문에 80286에서 보호모드를 사용하는 경우는 거의 없었다. 80286은 8086과 같이 16비트 CPU이다. 보호모드를 지원하는 것과 주소 버스가 24비트(16MB 메모리 지원)인 것을 빼면 8086과 다를 빠 없었다. (속도가 빠른 8086 이라고 보면 된다.) 그래서 80286은 그냥 이 정도 설명에서 넘어가도록 하겠다.

 

 80386(Intel386 DX)은 싱글유저 응용프로그램과 MS-DOS나 Windows같은 운영체제를 위해 디자인된 32비트 프로세서이다. 32비트 레지스터들과 32비트의 데이터버스, 주소버스를 가지고 있다.

이 프로세서는 4기가의 물리적 메모리(2의 32승)와 64테라바이트(2의 48승)의 가상 메모리를 지원한다. 80386이 중요한 이유는 이후 등장하는 모든 32비트 CPU가 80386을 근간으로 개발되었기 때문이다. 이를 IA-32 프로세서라고 한다. 때문에 80386은 모든 8086 family(8086, 8088, 80186, 80188, 80286)들과 하위 호환성을 지원한다. 또한 80386은 실제모드, 보호모드, 가상 8086모드 의 3가지 동작 모드를 지원한다. 여러모로 8086이나 80286의 내부구조에 비해 많은 부분이 변하였다.

 

 

[표 2-1-1] 참고

CPU 출시년도 트랜지스터수 제조 공정 패키지 최대 클럭 외부 데이터 버스 레지스터 주소 버스 L1 Cache L2 Cache
80286 1982 134,000 1.0 microns 68 pin PLCC or PGA 12.5 MHz 16 16 24 none none
80386 1985 275,000 1.0 microns 132 pin PGA or QFP 33 MHz 32 32 32 none external

 

2.2. 기본 구조 (Base Architecture)

 80386은 중앙 처리 장치(CPU, a central processing unit)과, 메모리 관리 장치(MMU, a memory management unit), 그리고 버스 인터페이스 장치(BIU, Bus Interface Unit)로 구성된다.

 

CPU(Central Processing Unit) 중앙처리장치는 실행장치(EU, execution unit)와 명령어 장치(instruction unit)로 구성된다. 실행장치(EU)는 ALU(arithmetic logic unit)와 8개의 32비트 범용 레지스트를 가지고 있다. (8086의 레지스터는 16비트) 80386도 8086처럼 명령어의 인출과 실행을 겹치도록하여(파이프라인 구조), 시스템의 성능을 최적화 시킨다.

 

MMU(Memory Management Unit) 메모리 관리 장치는 세그멘테이션 장치와 페이징 장치로 구성된다. 자세한 내용은 세그먼테이션 기법, 페이징기법에서 다룬다.

 

BIU(Bus Interface Unit) 이 장치는 여러 제어 신호와 함께, 386의 32비트 주소 버스와 데이터 버스를 관리한다. 8086의 BIU처럼 프로세서가 명령어 인출을 기다리지 않도록 명령어 큐를 가득채우는 일을 한다.(80386에서는 명령어 큐 16바이트로 확장)

 

[그림 2-2-1] 80386의 기본 구조

 

  

2.3. 동작모드 

 

2.3.1. 실제모드 (real mode)

 CPU에 처음 전원이 들어오면 80386은 실제 모드에서 시작된다. 이 모드의 80386은 8086과 기능이 완전히 동일하다.

주소 선은 20개의 하위 비트 A0-A19만 사용 되서 주소 공간이 1MB로 제한된다. 상위 주소선 A20-A31은 비활성화 된다. 그리고 8086의 세그먼티드 메모리 주소 지정 방식이 사용되며, 각 세그먼트의 크기는 64K로 제한된다. 또한 프로그래머는 80386의 32비트 레지스터를 사용할 수 있다.

 

2.3.2. 보호모드 (protected mode)

 80386의 강력하고, 고유한 기능을 사요하기 위해서는 보호모드에서 작동 되어야 한다. 보호모드에서는 가상메모리(세그먼테이션과 페이징 기법)을 지원하고, 개별 테스크에 특권 수준을 부여 하는 기능을 제공한다. 하위 특권 수준의 테스크는 상위 특권 수준을 가지고 있는 세그먼트의 프로그램이나 데이터를 엑세스 할 수 없다. 이 방식으로 운영체제는 각각으로부터 자신이 보호되도록 여러 개의 프로그램을 수행 시킬 수 있다. 자세한 부분은 보호 모드에서 알아 보도록 하자.

 

2.3.3. 가상 8086 모드(virtual 8086 mode)

 이 모드에서는 80386은 각각의 실제 모드 프로그램에 자신의 1MB 메모리 블록을 할당한다. 이러한 방식으로 여러 개의 8086/88 프로그램을 각각으로부터 보호하면서 동시에 실행할 수 있다. 동시에 실행시킬 수 있는 프로그램의 수는 제한이 없다. 가상 386모드는 보호 모드의 특징이다. (동시에 보호모드와 가상 8086모드를 동작 시킬 수 있다.) 각 8086테스크에는 가장 낮은 특권 수준이 부여되므로 다른 세그먼트에 있는 프로그램이나 데이터는 엑세스할 수 없으며, 따라서 각 테스크가 보호된다.

 

'80x86 프로세서' 카테고리의 다른 글

3장. 일반적인 개념들  (0) 2010.04.12
2장. 80386 프로세서 (3/3)  (0) 2010.04.12
2장. 80386 프로세서 (2/3)  (0) 2010.04.12
1장. 8086/8088 프로세서 (2/2)  (2) 2010.04.12
1장. 8086/8088 프로세서 (1/2)  (3) 2010.04.12

1장. 8086/8088 프로세서 (2/2)

  

상태플래그와 제어 플래그

 

[그림  1-5-2] 제어 레지스터 (상태플래그, 제어플래그)

  

플래그

설명

1 일때

0 일때

OF(overflow) 자리 넘침 OV(overflow) NV(not overflow)
DF(direction) 방향 DN(down) UP(up)
IF(interrupt) 가로채기 EI(enable) DI(disable)
SF(sign) 부호 NG(negative) PL(plus)
ZF(zero) 영(0) ZR(zero) NZ(not zero)
AF(aux,carry) 하위 4bit 캐리 AC(auc,carry) NA(not aux)
PF(parity) 패리티 PE(parity even) PO(parity odd)
CF(carry) 자리 올림 CY(carry) NC(not carry)

 

CF(Carry Flag)
 연산 명령을 실행한 후에 최상위 비트에서 덧셈에 의한 자리 올림(carry)이나 뺄셈에 의한 자리 내림(borrow)이 있을 경우 Set(해당 bit가 1이 되면 set, 0이 되면 reset)된다. 바이트 단위 연산일 때는 D7비트, 워드 단위일 때는 D15 비트가 대상이 된다. 논리 연산 명령에서는 0으로 reset된다. 로테이토, 쉬프트 명령에서는 해당 데이터의 최상위 또는 최하위 비트가 CF로 전송된다.


MSB (Most Significant Bit) : 최상위 비트
LSB (Least Signficant Bit) : 최하위 비트

 

PF(Parity Flag)

 데이터 전송 등에 따른 결과가 짝수 패리티인 경우에 set되고, 홀수 패리티일 때 reset된다. 이 플래그는 주로 데이터 전송시 에러가 발생 했는지 발생하지 않았는지 조사할 때 쓰인다. 하드웨어가 처리하는 부분이므로 프로그래머 입장에서는 신경쓰지 않아도 된다.


AF(Auxiliary Flag)

 산술 연산 도중에 하위 4비트에서 상위 4비트로 자리 올림이 생기거나, 또는 상위 4비트에서 하위 4비트로 자리 내림이 있을 때 1로 set된다. 이 플래그는 10진 연산의 경우 보정하는데 사용된다.


ZF(Zero Flag)

 각 연산의 결과가 0이 될 경우 set된다. 비교 명령을 실행하면 비록 레지스터 내용은 변하지 않지만 실행 결과에 따라서 set될 수 있다.


SF(Sign Flag)

 연산 결과 최상위 비트가 1이 되면 set된다. SF는 연산 후 그 결과 값의 부호를 나타내는데 사용하며 최상위 비트가 0일 경우 양수, 1일 경우엔 음수가 된다.

 

OF(Over Flow Flag)

 연산결과 오버플로우가 발생했을때 set 된다. 오버플로우가 생기면 원하는 데이터가 망가져서 원하는 데이터를 얻을 수 없으며 프로그램엔 치명적인 에러를 방생한다.0으로 나누었을 때 발생하는 오버플로우에 대해서는 CPU에 의해서 내부적으로 오버플로우 인터럽트가 발생하고, 프로그램은 보통 정지하게 된다.


IF(Interrupt Enable Flag)

 하드웨어에 의한 인터럽트를 받아들일 것인가, 받아들이지 않을 것인가를 나타낸다. 1로 set되어 있을 경우 인터럽트를 받아들이고, 0으로 reset되어 있을 경우엔 받아들이지 않는다. 단 NMI(Non-Maskable Interrupt)는 이 플래그의 값에 관계없이 받아들인다.

 

DF(Direction Flag)

 문자열에 관한 명령을 실행할 때, 이 비트에 따라서 소스 또는 데스티네이션 어드레스를 자동적으로 하나씩 증가 또는 감소 시킨다. 0일 때 어드레스가 자동적으로 증가하고, 1일 경우 어드레스가 감소한다.

 

TF (Trap Flag)

 명령 실행 후에 CPU는 이 플래그를 조사하여 1이면 싱글 스텝 인터럽트를 발생한다. 이플래그를 1로 해두면 CPU는 하번에 1개의 명령만 실행한다. 이 기능을 이용하여 디버깅 프로그램을 만들 수 있다.

 

 

1.6. 세그먼티드 메모리

 

1.6.1. 메모리 맵 

 8086/88의 메모리 공간은 64KB 블록 16개로 분할되어 있다. 16진수 00000h 에서 FFFFFh로 끝나는 메모리 주소를 가지고 있다. 64K의 블록으로 분할되어 있기 때문에 16진으로 64K만큼 하나만 증가 시켜 버리면 블록이 바뀌기 때문에 편리하다. (메모리 주소에서 20000h 는 10000h 보다 65,536바이트/64K 높은 위치에있다.)

 

 [그림 1-6-1]에서 보는 것과 같이 메모리 주소가 일직선으로 연속된 공간이라고 생각하고, 시스템 메모리가 어떻게 할당 되어 있는가를 보이고있는 것을 메모리 맵(memory map)이라고 한다. 예를 들면 RAM영역은 00000h 에서 9FFFFh까지 할당되었고, Video Display RAM 영역은 A0000h에서 BFFFFh 까지 할당, ROM영역은 C0000h에서 FFFFFh까지 할당된다. 프로그래머는 이를 확실하게 알아야 정확히 메모리의 어느 부분에 안전하게 데이터를 적재할 수 있다.

 

[그림 1-6-1] 8086/88의 메모리 맵

 

 

 아래의 [그림 1-6-2]는 MSDOS의 메모리 맵이다. 도스는 8086 CPU에서 설계 되었다. 따라서 메모리의 크기가 1MB로 한정되었다. 호환성의 이유로 1MB의 주소 공간을 아래의 메모리 공간처럼 블록으로 분할 하였다. (메모리의 1MB는 640K의 사용자 메모리와 384K의 시스템 메모리로 구성)

도스 시절부터 컴퓨터를 사용했다면 아마, 게임을 하기위에 640K 의 메모리를 최대한 활용할려고 애를써본 기억이 있을 것이다. 이때의 메모리가 도스의 유저메모리 공간이다.

 

[그림 1-6-2] MSDOS 의 메모리 맵

 

 

 

1.6.2. 세그먼트 레지스터, 오프셋 레지스터(포인터, 인덱스 레지스터)

 1.5. 레지스터의 세그먼트 레지스터를 다시 한번 살펴보자. 64K로 나눈 공간을 세그먼트라고 하였다. 그 세그먼트를 저장하는 레지스터가 세그먼트 레지스터이다. 8086/88의 세그먼트 레지스터는 총 4가지가 있다. (코드 세그먼트(CS), 데이터 세그먼트(DS), 스택 세그먼트(SS), 엑스트라 세그먼트(ES) - [그림 1-5-1] 8086 레지스터의 구성 참고)

여기서 코드 세그먼트는 프로그램 명령어가 저장된 세그먼트 영역의 시작주소를 저장하고, 데이터 세그먼트는 프로그램에 사용되는 데이터가 저장된 세그먼트의 첫 주소를 저장한다. 엑스트라 세그먼트 또한 데이터 세그먼트와 같다.(대개 공유 데이터를 저장하는데 사용된다.) 그리고 스택 세그먼트는 인터럽트와 서브루틴의 반환 주소를 저장하는데 사용된다. (스택에 대해서는 2부 어셈블리 에서 자세하게 소개하겠다.) 또 4개의 세그먼트가 반드시 분리 되서 정의될 필요는 없다. [그림 1-6-3]을 보면 SS영역과 ES이 서로 겹쳐 있는 걸 알 수 있다. 실제로 4개의 세그먼트가 완전히 같은 경우도 허용된다. (CS=DS=ES=SS) 

 

[그림 1-6-3] 각 세그먼트의 시작 주소가 세그먼트 레지스터에 저장되어 있는 것을 표현한 것이다.  

 

 세그먼트 레지스터의 값은 64K로 나눈 세그먼트 블록의 첫번 째 주소(base address)이기 때문에, 각 세그먼트 블록 안의 메모리 영역에 접근하기 위해서는 오프셋 레지스터(포인트, 인덱스 레지스터)가 필요하다. 1.5. 레지스터의 포인터 레지스터와 인덱스 레지스터를 다시 자세히 알아보자.

 

[표 1-6-1] 오프셋 레지스터 - SI, DI, IP, SP, BP

SI(Source Index      )

DI(Destination Index)

IP(Instruction Index )

SP(Stack Pointer      )

BP(Base Pointer       )

 

 다시 한번 강조하지만 세그먼트 레지스터로는 64KB 크기의 세그먼트 첫 번째 주소밖에 지정하지 못한다. 64KB내에서 원하는 임의의 주소를 지정하기 위해서 16비트 크기의 레지스터가 하나 더 필요한데 이때 사용하는 레지스터가 오프셋 레지스터이다.

 

SI(Source Index), DI(Destination Index)
 문자열을 다루는 명령에서 소스 데이터의 오프셋 어드레스를 가리킬 때는 SI를 사용하고, 데스티네이션 어드레스를 가리킬 때 DI를 사용한다.
 
IP(Instruction Pointer)
 명령코드가 들어있는 세그먼트의 오프셋 어드레스를 지정하는데 사용한다. 이때의 세그먼트를 지정하기 위해서는 반드시 CS를 사용해야 한다. 이 포인터는 프로그래머는 사용할 수없다.

SP(Stack Pointer)
 스택 세그먼트의 오프셋 어드레스를 지정하는데  사용된다. 스택 세그먼트를 지정하는 세그먼트 레지스터로는 SS만을 사용해야 한다. 하지만 스택내의 오프셋을 나타내는데는 SP외에 BP로도 사용 할 수 있다.
 
BP(Base Pointer)
 SP와 마찬가지로 스택의 오프셋을 가리키는데 사용한다. SP와 다른 점은 PUSH와 POP명령에 의해 자동적으로 변하지 않는다는 것이다. 전달받은 인수를 함수 내부에서 가리킬 때 주로 사용한다.

 

1.6.3. 세그먼트 메모리 기법 

 세그먼트 내에서 주소는 0에서부터 시작하여 FFFF까지 이다.(64K의 길이, 오프셋 레지스터의크기는 16비트이기 때문이다.) 세그먼트 내에서의 주소는 오프셋(offset) 또는 논리 주소(logical address)라고 한다. 그럼 물리 주소(physical memory)는 무엇인가? 바로 메모리의 실제 주소를 뜻한다.

 세그먼트 레지스터는 16비트이기 때문에 실제 메모리 주소(20비트)에 분할된 세그먼트 블록의 첫 주소를 저장하지 못한다. 해결 방법은 실제주소의 하위 비트를 4개를 생략하고 저장을 한다. 반대로 세그먼트 레지스터의 값을 실제 주소로 바꿀 땐 하위비트 뒤에 0000을 추가한다. (이는 레지스터의 내용에 16을 곱한것이다.) 예를 들어 [그림 1-6-4]를 보자. 그림에서 색칠되어 있는 부분을 코드 세그먼트(CS)라고 가정하자. 코드 세그먼트의 논리 주소(오프셋)을 0250h 라면(CS : 8000, Offset : 0250) , 실제 주소(물리주소)는 80000 + 0250으로 80250h 이다.

 

   80000  ( CS의 8000h 의 하위비트에 0 추가 ) -> 16진수이기 때문에 0을 한개 붙였다. 2진수일경우 0 4개를 추가한다.

+)_0250  ( CS의 오프셋 )

--------- 

   80250  (실제 물리 주소)

 

세그먼트 레지스터와 오프셋 레지스터, 이 두개의 16비트 레지스터를 이용해서 20비트의 메모리에 접근 하는 방법을 세그먼트 메모리 기법이라고 한다.

 

물리 주소 : 20비트의 길이를 가지고 있고, BIU가 주소 버스 선에 내보내는 실제의 이진 코드

논리 주소 : 주어진 세그먼트의 0위치로 부터의 오프셋

  

[그림 1-6-4] 세그먼트화된 메모리맵, 실제 주소 모드

 

 

 두 세그먼트가 겹치는 경우가 있다고 했다. 심지어 4개의 세그먼트까지 중복으로 사용 가능하다. 여기서 발생하는 문제가 있는데, 바로 세그먼트와 오프셋 조합이 중복되는 경우이다. 이는 물리 주소가 중복된다는 말과 동일하다.  이 때 데이터가 서브루틴 스택에 덧쓰기를 하거나 반대로 스택에 저장되는 주소가 데이터를 덧쓰게 되면 큰 문제가 발생한다. 그렇기 때문에 세그먼트가 겹칠때에는 각별히 주의해야한다.

 

물리 주소가 겹치는 예

ES : 52B9h, offset : D470h -> 52B90 + D470 = 60000h

SS : 5D27h, offset : 2D90h -> 5D270 + 2D90 = 60000h

 

마지막으로 세그먼트와 오프셋의 표기법을 알아보자.

스택 세그먼트의 논리 주소 2D90h를 표현 할려면 SS:2D90h 라고 쓴다. 이렇게 표현하면 물리 주소는 같더라도 프로그래머가 알아보기가 명확해진다.

 

각 세그먼트별로 사용해야하는 오프셋 레지스터는 2부 어셈블리에서 자세하게 배운다.

'80x86 프로세서' 카테고리의 다른 글

3장. 일반적인 개념들  (0) 2010.04.12
2장. 80386 프로세서 (3/3)  (0) 2010.04.12
2장. 80386 프로세서 (2/3)  (0) 2010.04.12
2장. 80386 프로세서 (1/3)  (0) 2010.04.12
1장. 8086/8088 프로세서 (1/2)  (3) 2010.04.12

1장. 8086/8088 프로세서 (1/2)

 

 

1.1. 개요

 16비트 프로서세인 8086 마이크로프로세서(이하 8086)는 1970년대 후반에 등장하였다. 16비트 명령어가 도입 되었고, 하드웨어에 의한 곱셈과 나눗셈을 수행할수 있었다. 그리고 20비트의 주소 버스를 사용하여 1MB까지의 메모리를 엑세스 할 수 있었다. 이후 등장하는 80x86 마이크로프로세서(이하 80x86)들은 8086을 기초로 만들어 지고, 발전 됐다. 이 말은 곧 하위 호환성을 가진다는 말이 될 것이다. 실제로 8086용으로 제작된 프로그램이 지금 CPU에서도 잘 작동 된다. 따라서 8086을 잘 이해한다면 상위 CPU모델들을 이해하는데 큰 도움이 될 것이다.

 

 

 

[표 1-1-1] 참고

CPU 출시년도 트랜지스터수 제조 공정 패키지 최대 클럭 외부 데이터 버스 레지스터 주소 버스 L1 Cache L2 Cache
8086 1978 29,000 3.0 microns 40 pin DIP 10 MHz 16 16 20 none none
8088 1979 29,000 3.0 microns 40 pin DIP 10 MHz 8 16 20 none none
 
 

1.2. 8086의 구조

 8086은 버스 접속 장치(BIU, bus interface unit)와 실행 장치(EU, execution unit)로 구성된다. 여기서 버스 접속 장치(이하 BIU)와 실행 장치(이하  EU)를 알아 보자.

 

[그림 1-2-1] 참고

 

 

BIU : 프로세서와 외부 장치와의 데이터 전달에 필요한 메모리주소나 I/O주소의 생성을 담당하는 하드웨어 기능 제공

EU : BIU로 부터 프로그램 명령어 코드와 데이터를 받아들여, 명령어를 수행한 다음, 범용 레지스터에 결과를 저장하는 기능 제공. EU는 BIU를 통해서 모든 데이터를 받고 보낸다.

 

 

1.3. 인출(fetch) 사이클과 실행(excute) 사이클

 

인출(fetch) : IP(Instruction pointer) 레지스터가 가리키고있는 주소의 명령어를 가져 오는 것.

실행(excute) : 인출한 명령어를 실행 하는것.

 

 8086은 동작 속도를 높이기 위해서 앞에서 설명한 BIU와 EU로 구성 하였다. 이는 인출 사이클과 실행 사이클이 중첩되게 할 수 있다. 이를 알아 보기 위해 8086이 처음 시작할 때 하는 행동을 살펴보자.

 

① BIU가 명령어 포인터 레지스터의 내용을 주소 버스로 보내어 메모리의 선택된 바이트 혹은 워드가 BIU로 읽혀 들어오게 한다.

② IP 레지스터를 하나 증가 시켜 다음 명령어 인출을 준비한다. (크기에 따라 둘 이상 증가 되기도 한다.)

③ BIU에 들어온 명령어는 큐(queue)에 저장된다. 큐는 선입출(FIFO)방식인 저장 레지스터이다.

④ 제일 초기엔 큐가 비어 있기 때문에, EU는 바로 큐에서 명령어를 꺼내어 실행한다.

⑤ EU가 가지고온 명령어를 실행하고 있는 동안, BIU는 새로운 명령어 인출을 시작한다. 첫번째 명령어의 실행 시간에 따라 다르지만, EU가 다음 명령어를 큐에서 꺼낼 준비가 될 때 까지는 BIU는 명령어 큐에 여러 개의 명령어를 저장 할 수 있다.

⑥ BIU는 큐에 명령어를 채우고, EU는 이 명령어를 인출하고 실행하는 사이클이 계속 된다.

 

 BIU는 명령어 큐에 두 바이트 이상 저장 공간이 생길 때 마다 새 명령어를 인출 하는데, 이러한 파이프 구조는 BIU가 새 명령어를 인출 할 때 까지 기다리지 않고, EU가 거의 연속적으로 명령어를 실행 할 수 있게 한다. 이는 CPU의 동작 속도를 크게 향상 시킨다.

 

 하지만 EU가 대기 모드에 들어가는 경우가 있는데, 3가지 조건이 있다. 첫번 째 조건은 명령어가 큐에 있지 않는 메모리 위치를 엑세스 할 필요가 있을 때 일어난다. BIU는 명령어 인출을 보류하고 이 메모리 위치의 주소를 출력한다. 메모리 엑세스를 기다린 후에 EU는 큐로 부터 명령어를 꺼내어 실행을 재개 하고, BIU는 계속해서 명령어 큐를 채운다. 두 번째 조건은 실행 될 명령어가 점프 명령어일 때 일어난다. 이 경우, 제어는 새로운 주소로 전달(비순차적이다) 되어야 하지만 큐는 명령어가 항상 순차적으로 실행된다고 가정하고 틀린 명령어 코드를 저장하고있다. EU는 점프 주소에 있는 명령어가 인출되는 동안 기다려야 한다. 현재 큐에 들어가 있는 모든 명령어는 버려진다.(덮어쓰기가 이루어짐) 마지막 세번 째 조건은 BIU가 명령어 인출을 멈추게 하는 경우이다. 이는 실행속도가 느린 명령어를 실행할 때 일어난다. 이런 명령어들은 하나만 실행 해도 명령어 큐가 다 차 버린다. 따라서 BIU는 EU가 큐에서 하나 또는 두 바이트를 꺼내 갈때 까지 기다린 후에 다시 인출을 진행한다.

 

[그림 1-3-1] 인출과 실행 사이클, 명령어 파이프 라인

 

 

1.4. 8088 프로세서란? 

 위의 [표 1-1-1 ] 참고를 보면 알겠지만, 기본적인 구조는 8086과 동일하다. 유일한 차이점은 BIU이다. 8086은 16비트 버스이지만, 8088은 그 반인 8비트 버스이다. 명령어 큐 사이즈도 작아졌다.(8086 명령어 큐 사이즈 : 6바이트, 8088 명령어 큐 사이즈 4바이트) 지금으로 치자면 팬티엄의 보급형으로 나온 셀러론급 CPU라고 생각해도 무방하다. EU는 동일하기 때문에 프로그래머 입장에서는 프로그래밍하는 것이 동일하다. 그러므로 8086 구조만 알면 된다. (8088용 프로그램은 변경없이 8086에서 실행 가능하다.)

 

 

1.5. 레지스터

 레지스터란 CPU가 여러 가지 명령을 실행할 때, 데이터나 계산의 중간 결과를 일시적으로 보관하거나, 각종 연산의 처리, 주소 지정등에 사용되는 CPU내부의 램(RAM)을 말한다. 하드웨어 적으로 외부 메모리인 램(RAM)이나 롬(ROM)과 달리 CPU안에 들어 있으며, 버스 인터페이스의 내부 버스에 직접 연결되어 있기 때문에 외부 메모리에 비해서 CPU의 엑세스 시간이 훨씬 짧고 지정 방법도 간단하다.

 

[그림 1-5-1] 8086 레지스터의 구성

 

범용 레지스터(General Registers)

 데이터 레지스터, 데이터 그룹이라고도 불리며, 누산기(AX 레지스터, Accumulation)와  BX, CX, DX 레지스터로 구성된다. 각 레지스터의 크기는 16비트지만, 바이트(8비트) 혹은 워드(16비트) 단위로 엑세스 할 수 있다.(예- AX는 AH와 AL로 구성) 각각은 데이터를 다룰 때 구분없이 사용되거나, 각각 특별한 용도로 사용된다. 대개 다음 명령어에 사용될 임시 결과를 저장하는데 사용된다.

 

□ AX(Accumulation, AH + AL = AX)
 주로 산술 연산(덧셈(AND), 뺄샘(SUB), 곱셈(MUL), 나눗셈(DIV)), 논리 연산(AND, OR, XOR등)의 대상이 된다. C함수는 함수 내에서 계산한 값을 리턴 할 때 AX레지스터에 넣어서 리턴한다.
 
□  BX(Base, BH + BL = BX)
 메모리상에 있는 변환표의 시작 번지를 가리키거나, 간접 어드레싱 모드에서 오프셋 어드레스를 가리키는데 사용된다.
 
□ CX(Counter, CH + CL = CX)
 주로 카운터하는데 사용하며, 카운터로 사용 될 경우엔 다른 레지스터로 대체할 수 없다. 문자열(string)을 다루는 명령(MOVSB, SCASB 등)이나 루프 명령(LOOP, REP)에서 카운터로 사용하거나, 쉬프트 명령에서 쉬프트 수, 로테이트 명령의 로테이트 수를 나타내는데 사용한다.
 
□ DX(Data, DH + DL = DX)
Port로의 입출력 명령(IN, OUT)에서 포트 어드레스를 지정하거나, 곱셈,나눗셈 명령에서 상위워드를 저장하는 데이터 레지스터로 사용한다.

 

세그먼트 레지스터(Segment Registers)

 8086의 CPU레지스터는 16비트이다. 하지만 8086의 어드레스 핀수는 20개이다. 따라서 최대 1MB(2의 20승)의 메모리를 가질 수 있다. 16비트 레지스터로 지정할 수있는 최대 메모리는 64KB(2의 16승)이므로, 이러한 1MB의 메모리를 전부 지정할 수 없다. 해결 방법으로 나온 것이 1MB의 메모리를 64KB단위로 나누어 관리하는 것이다. 이렇게 나눈 64KB 메모리 공간을 세그먼트라고 하고, 이 세그먼트는 16의 배수인 메모리 주소에서만 시작한다. 이 세그먼트의 시작 주소를 저장하는 레지스터가 세그먼트 레지스터이다. 자세한건 뒤에 나올 세그먼티드 메모리에서 다룬다.

 

포인터 레지스터와 인덱스 레지스터(Pointer Registers, Index Register) 

 16비트 크기를 가지는 오프셋 레지스터이다. 범용 레지스터와는 달리 상위및 하위 바이트로 분리해서 사용할 수 없다. 세그먼트 레지스터만 가지고서는 64KB 메모리공간의 시작 주소밖에 표시할 수 없으므로, 각 세그먼트 내의 주소를 나타내기 위해 또 하나의 16비트 레지스터가 필요한데, 이때 사용되는 레지스터를 포인터레지스터 또는 인덱스 레지스터이다. (메모리에 대한 포인터로 사용된다.) 자세한건 뒤에 나올 세그먼티드 메모리에서 다룬다.


'80x86 프로세서' 카테고리의 다른 글

3장. 일반적인 개념들  (0) 2010.04.12
2장. 80386 프로세서 (3/3)  (0) 2010.04.12
2장. 80386 프로세서 (2/3)  (0) 2010.04.12
2장. 80386 프로세서 (1/3)  (0) 2010.04.12
1장. 8086/8088 프로세서 (2/2)  (2) 2010.04.12

+ Recent posts