[System] 80x86 시스템 CPU 구조와 레지스터
(1) 80x86 시스템 CPU 구조와 레지스터
1-1. 80x86 시스템
-
8086/8088 시스템은 XT라고 칭했던 인텔 CPU의 IBM PC 중 아주 초기 보급형 모델
-
그러다 AT라는 80286 시스템 발표, 이후부터 익숙한 이름의 모델이 등장
-
바로 80을 떼고 80386을 386, 80486을 486으로 칭했던 시스템들이며 80x86은 이런 시스템을 통칭하는 말
1-2. 80x86 시스템 CPU 구조
1-2-1. 연산 장치
-
연산 장치(ALU)는 CPU(중앙 처리 장치) 핵심 부분 중 하나이며, 산술과 논리 연산을 수행하는 연산 회로 집합으로 구성
구성 요소 | 기능 | |
내부 장치 | 가산기(Adder) | 덧셈 연산 수행 |
보수기(Complementer) | 뺄셈 연산 수행, 1의 보수나 2의 보수 방식 이용 | |
시프터(Shifter) | 비트를 오른쪽 / 왼쪽으로 이동하여 나눗셈, 곱셈 연산 수행 | |
관련 레지스터 | 누산기(Accumulator) | 연산의 중간 결과 저장 |
데이터 레지스터 (Data Register) |
연산에 사용할 데이터 저장 | |
상태 레지스터 (Status Register) |
연산 실행 결과로 나타나는 양수나 음수, 자리 올림, 오버플로 상태 기억 |
1-2-2. 제어 장치
-
제어 장치(CU)는 입출력, 기억 장치, 연산 장치를 제어하고 감시
-
주기억 장치에 저장된 명령을 차례로 해독 > 연산 장치로 보내 처리하도록 지시
구성 요소 | 기능 | |
내부 장치 |
명령 해독기 (Instruction Decoder) |
명령 레지스터에 있는 명령 해독 > 부호기로 전송 |
부호기(Decoder) | 명령 해독기가 전송한 명령 > 신호로 만들어 각 장치로 전송 | |
주소 해독기(Address Decoder) |
명령 레지스터에 있는 주소 해독 > 메모리 실제 주소로 변환 > 데이터 레지스터에 저장 |
|
관련 레지스터 |
프로그램 카운터 (Program Counter) |
다음에 실행할 명령 주소를 저장 |
명령 레지스터 (Instruction Register) |
현재 실행 중인 명령을 저장 | |
메모리 주소 레지스터 (Memory Address Register) |
주기억장치의 번지 저장 | |
메모리 버퍼 레지스터 (Memory Buffer Register) |
메모리 주소 레지스터에 저장된 주소 실제 내용 저장 |
1-3. 레지스터
-
처리 중인 데이터나 처리 결과를 임시 보관하는 CPU 안의 기억장치
-
대개 연산 장치나 제어 장치에 함께 포함
1-3-1. 레지스터 종류 & 기능
-
사람이 일상 생활에서 메모하는 것처럼, 프로그램도 메모를 하는 데 이때 메모지 역할을 하는 것
-
프로그램이 사용하는 메모지 종류와 내용을 알면 프로그램 동작 원리 이해에 도움
1-3-2. 범용 레지스터
범주 | 80386 레지스터 | 이름 | 비트 | 용도 |
범용 레지스터 (General Register) |
EAX | 누산기(Accumulator) | 32 |
주로 산술 연산에 사용 (함수 결과 값 저장) |
EBX |
베이스 레지스터 (Base Register) |
32 |
특정 주소 저장 (주소 지정 확대하는 인덱스로 사용) |
|
ECX |
카운트 레지스터 (Count Register) |
32 |
반복적 실행되는 특정 명령에 사용 (루프 반복 횟수 & 좌우 방향 시프트 비트 수 기억) |
|
EDX |
데이터 레지스터 (Data Register) |
32 | 일반 자료 저장(입출력 동작에 사용) |
-
연산 장치가 수행한 계산 결과의 임시 저장, 산술 및 논리 연산, 주소 색인 등 여러 목적으로 사용
-
80386 CPU에서 사용하는 범용 레지스터는 EAX, EBX, ECX, EDX 등이 있음
-
앞의 E는 '확장된'을 의미하며, 32비트 레지스터
-
이 레지스터의 오른쪽 16비트를 각각 AX, BX, CX, DX라고 하며, 다시 둘로 나뉨
-
예를 들어, AX는 왼쪽 8비트 상위 부분을 AH, 오른쪽 8비트 부분을 AL이라 함
EAX 레지스터
-
누산기인 EAX 레지스터는 입출력과 대부분의 산술 연산에서 사용 (예 : 곱셈, 나눗셈, 변환 명령은 EAX 사용)
-
사용 시에 더 효율적인 기계 코드를 생성하는 명령도 있으며, Win32 API 함수들은 모두 리턴 값을 EAX에 저장한 후에 리턴
EBX 레지스터
-
DS 세그먼트의 포인터를 주로 저장하며, ESI나 EDI와 결합하여 인덱스에 사용
-
BX는 메모리 주소 지정을 확장하기 위한 인덱스로 사용할 수 있는 유일한 범용 레지스터
ECX 레지스터
-
루프가 반복되는 횟수를 제어하는 값, 왼쪽이나 오른쪽으로 이동되는 비트 수 등을 포함할 수 있음
EDX 레지스터
-
입출력 연산에 사용하며, 큰 수의 곱셈과 나눗셈 연산에서 EAX와 함께 사용
1-3-3. 세그먼트 레지스터
범주 | 80386 레지스터 | 이름 | 비트 | 용도 |
세그먼트 레지스터 (Segment Register) |
CS |
코드 세그먼트 레지스터 (Code Segment Register) |
16 |
실행할 기계 명령어가 저장된 메모리 주소 지정 |
DS |
데이터 세그먼트 레지스터 (Data Segment Register) |
16 |
프로그램에서 정의된 데이터, 상수, 작업 영역 메모리 주소 지정 |
|
SS |
스택 세그먼트 레지스터 (Stack Segment Register) |
16 |
프로그램 스택 세그먼트 시작 주소 저장 메모리 상에 스택 구현을 가능하게 함 |
|
ES, FS, GS |
엑스트라 세그먼트 레지스터 (Extra Segment Register) |
16 | 문자 연산과 추가 메모리를 지정하는 데 사용하는 여분의 레지스터 |
-
세그먼트는 프로그램에 정의한 메모리 상의 특정 영역 (코드, 데이터, 스택 등을 포함)
-
세그먼트는 메모리 대부분에 위치 가능, 실제 모드에서는 최대 64KB 크기까지 가능
-
각 세그먼트의 주소를 지정하고, 특히 PC 계열에 사용하는 인텔 프로세서는 자신의 주소 지정 기능을 제공
-
기본으로 CS, DS, SS 등 레지스터 세 개를 사용하며, ES나 FS, GS 레지스터는 여분으로 프로그램 크기나 필요에 따라 사용 가능
CS 레지스터
-
코드 세그먼트는 실행될 기계 명령을 포함
-
코드 세그먼트의 시작 주소를 가리키며, 일반 프로그래밍에서는 이 레지스터를 직접 참조할 필요 X
DS 레지스터
-
데이터 세그먼트는 프로그램에 정의된 데이터, 상수, 작업 영역을 포함
-
데이터 세그먼트의 시작 주소를 가리키며, 프로그램은 참조하려는 데이터의 오프셋을 DS 레지스터에 저장된 주소 값에 더해 데이터 세그먼트 안의 데이터를 참조
SS 레지스터
-
스택 세그먼트는 프로그램 실행 시, 실행 과정에서 필요 데이터나 연산 결과 등을 임시로 저장 / 삭제하는 목적 사용
-
스택 세그먼트의 시작 주소를 가리킴
ES / FS / GS 레지스터
-
ES 레지스터는 추가로 사용된 데이터 세그먼트 주소를 가리킴
-
메모리 주소 지정을 다루는 문자 데이터 연산에 사용하는 데, 이때 EDI 레지스터와 함께 사용
-
FS와 GS 레지스터도 목적은 비슷, 실제로는 거의 사용 X
2-3-4. 포인터 레지스터
범주 | 80386 레지스터 | 이름 | 비트 | 용도 |
포인터 레지스터 (Pointer Register) |
EBP |
베이스 포인터 (Base Pointer) |
32 |
SS 레지스터와 함께 사용 스택 안의 변수 값을 읽는 데 사용 |
ESP |
스택 포인터 (Stack Pointer) |
32 |
SS 레지스터와 함께 사용 스택 가장 끝 주소를 가리킴 |
|
EIP |
명령 포인터 (Instruction Pointer) |
32 |
다음 명령어 오프셋(상대 위치 주소)을 저장 CS 레지스터와 합쳐 다음에 수행할 명령 주소 형성 |
-
프로그램 실행 과정에서 사용하는 주요 메모리 주소 값을 저장
EBP 레지스터
-
스택 세그먼트에서 현재 호출해서 사용하는 함수의 시작 주소 값 저장
-
함수로 전달되는 지역 변수 등을 참조할 때 기준이 됨
-
ESP 레지스터와 함께 써서 스택 프레임을 형성하기도 함
-
스택 프레임 기법은 함수가 호출될 때 ESP를 EBP에 저장하고 있다가 (mov %esp, %ebp) 모든 루틴이 끝나고 함수를 리턴하면 ESP 값을 돌려주어 스택 형성에 문제가 생기지 않도록 함
-
실제 메모리 상 주소를 참조할 때 SS 레지스터와 함께 사용
ESP 레지스터
-
현재 스택 영역에서 가장 하위 주소를 저장
-
스택은 높은 주소 > 낮은 주소로 이동하면서 데이터를 저장하므로, 스택이 확장되면 스택 포인터도 높은 주소에서 낮은 주소로 값 변경
-
EBP와 마찬가지로 실제 메모리 상 주소를 참조할 때 SS 레지스터와 함께 사용
EIP 레지스터
-
다음에 실행될 명령의 오프셋을 포함
-
현재 실행 중인 코드 세그먼트에 속한 현재 명령을 가리킴
-
실제 메모리 상 주소를 참조할 때 CS 레지스터와 함께 사용
1-3-5. 인덱스 레지스터
범주 | 80386 레지스터 | 이름 | 비트 | 용도 |
인덱스 레지스터 (Index Register) |
EDI |
목적지 인덱스 (Destination Index) |
32 | 목적지 주소 값 저장 |
ESI |
출발지 인덱스 (Source Index) |
32 | 출발지 주소 값 저장 |
-
데이터를 복사할 때 출발지와 목적지 주소를 각각 가리키는 레지스터로 사용
-
EDI, ESI가 있으며 오른쪽 16비트를 각각 DI, SI라고 함
ESI & EDI 레지스터
-
주로 메모리의 한 영역(Source)에서 다른 영역(Destination)으로 데이터를 연속적으로 복사할 때 사용
-
예로 strcpy(Destination, Source) 함수는 Source의 문자열을 Destination으로 복사할 때 두 메모리 주소를 저장하는 데 ESI와 EDI 레지스터를 사용
1-3-6. 플래그 레지스터
범주 | 80386 레지스터 | 이름 | 비트 | 용도 |
플래그 레지스터 | EFLAGS |
플래그 레지스터 (Flag Register) |
32 | 연산 결과 및 시스템 상태와 관련된 여러 플래그 값 저장 |
-
크기가 32비트이며, 컴퓨터의 다양한 상태를 나타내는 비트를 포함
-
상태 플래그, 제어 플래그, 시스템 플래그로 구성됨
-
위 그림에서 각 비트는 1(Set), 0(Clear) 값을 가지며, 비교 연산과 산술 연산을 포함하는 많은 명령이 플래그 상태를 변화시키고, 어떤 명령은 다음 행동을 결정하려고 플래그 상태를 점검함
상태 플래그 (State Flag)
-
상태 플래그(0, 2, 4, 6, 7, 11비트)는 산술 명령(ADD, SUB, MUL, DIV) 결과를 반영
-
CF(Carry Flag / 비트 0) : 산술 연산 결과로 자리 올림이나 자리 내림이 발생할 때 세트된다. (STC, CLC 같은 어셈블리어 명령으로 값 수정 가능)
-
ZF(Zero Flag / 비트 6) : 산술 연산 결과가 0이면 세트(1), 0 이외에는 클리어(0)
-
OF(Overflow Flag / 비트 11) : 부호가 있는 수의 오버플로가 발생하거나 MSB(Most Significant Bit)를 변경했을 때 세트(1)
-
PF(Parity Flag / 비트 2) : 산술 연산 결과가 짝수이면 세트(1)
-
AF(Adjust Flag / 비트 4) : 8비트 피연산자를 사용한 산술 연산에서 비트 3을 비트 4로 자리올림하면 세트(1)
-
SF(Sign Flag / 비트 7) : 산술 및 논리 연산 결과가 음수이면 세트(1)
제어 플래그 (Control Flag)
-
제어 플래그인 DF(Direction Flag / 비트 10)는 스트링 명령(MOVS, CMPS, SCAS, LODS, STOS)을 제어
-
DF가 1이면 스트링 명령은 자동 감소함(스트링을 높은 주소에서 낮은 주소로 처리)
-
DF가 0이면 스트링 명령은 자동 증가(스트링을 낮은 주소에서 높은 주소로 처리)
-
STD / CLD 명령은 각각 DF 플래그가 세트(1)되고 클리어(0)됨
시스템 플래그 (System Flag)
-
운영체제나 장치 드라이버를 제어
-
TF(Trap Flag / 비트 8) : 디버깅 할 때 'Single Step Mode'를 활성화하면 세트되고, 비활성화하면 클리어
-
IF(Interupt enable Flag / 비트 9) : 프로세서의 인터럽트 처리 여부를 제어하며, IF가 세트되어 있으면 시스템의 인터럽트를 처리하고 클리어 되어 있으면 시스템 인터럽트 무시
-
IOPL(I/O Privilege Level / 비트 12, 13) : 현재 실행하는 프로그램이나 태스크의 입출력 특권 레벨을 지시하며, 현재 실행 중인 프로그램이나 태스크가 I/O 주소 공간에 접근하려면 CPL이 I/O 특권 레벨보다 낮거나 같아야 함
-
NT(Nested Task Flag / 비트 14) : 인터럽트하거나 호출된 태스크를 제어하며, 현재 태스크를 이전에 실행된 태스크와 연결했으면 세트되고, 연결하지 않으면 클리어
-
RF(Resume Flag / 비트 16) : 프로세서 디버그 예외 반응을 제어하며, 세트되어 있으면 디버그 오류를 무시하고 다음 명령어 수행
-
VM(Virtual 8086 Mode Flag /비트 17) : V86 모드를 활성화하면 세트, 사용하지 않고 보호 모드로 리턴 시 클리어
-
AC(Alignment Check /비트 18) : 메모리 참조 시에 정렬 기능을 활성화하면 세트
-
VIF(Virtual Interrupt Flag / 비트 19), VIP(Virtual Interrupt Pending / 비트 20) : 가상 모드 확장과 관련해 사용
-
ID(IDentification / 비트 21) : CPUID 명령의 지원 유무 결정
# Reference
https://www.hanbit.co.kr/store/books/look.php?p_code=B3283906872
'System' 카테고리의 다른 글
[System] 어셈블리어 기본 명령 (0) | 2020.03.20 |
---|---|
[System] 어셈블리어 구조 & 주소 (0) | 2020.03.20 |
[System] 80x86 시스템 메모리 구조와 동작 (0) | 2020.03.18 |
[System] 운영체제 이해 (0) | 2020.01.14 |