전 포스팅에서 레지스터란 CPU 내에서 데이터를 임시 저장하기 위한 고속의 작은 메모리 영역이라고 정의를 하였다.
1. x64 (64bit) 아키텍처: 레지스터
x64 아키텍처에는 범용 레지스터(General Register), 세그먼트 레지스터(Segment Register), 명령어 포인터 레지스터(Instruction Pointer Register, IP), 플래그 레지스터(Flag Register)가 존재한다.
1.1 범용 레지스터 (General Register)
주용도는 있지만, 그 외의 다양한 용도로 사용될 수 있는 레지스터이다. 각각의 범용 레지스터는 8바이트를 저장할 수 있고, 부호 없는 정수를 기준으로 2^64 - 1까지의 수를 나타낼 수 있다.
rax (accumulator register) | 함수의 반환 값 |
rbx (base register) | x64에서는 주된 용도 없음 |
rcx (counter register) | 반복문의 반복 횟수, 각종 연산의 시행 횟수 |
rdx (data register) | x64에서는 주된 용도 없음 |
rsi (source index) | 데이터를 옮길 때 원본을 가리키는 포인터 |
rdi (destination index) | 데이터를 옮길 때 목적지를 가리키는 포인터 |
rsp (stack pointer) | 사용중인 스택의 위치를 가리키는 포인터 |
rdp (stack base pointer) | 스택의 바닥을 가리키는 포인터 |
1.2 세그먼트 레지스터(Segment Register)
cs, ss, ds, es, fs, gs 총 6가지 세그먼트 레지스터가 존재하며, 각 레지스터의 크기는 16비트이다.
cs, ds, ss 레지스터는 코드 영역과 데이터, 스택 메모리 영역을 가리킬 때 사용되고, 나머지 레지스터는 운영체제 별로 용도를 결정할 수 있도록 범용적인 용도로 제작된 세그먼트 레지스터이다.
1.3 명령어 포인터 레지스터 (Instruction Pointer Register, IP)
프로그램은 일련의 기계어 코드들로 이루어져 있다. CPU가 어느 부분의 코드를 실행할지 가리키는게 명령어 포인터 레지스터의 역할이다. 명령어 레지스터는 rip 이며, 크기는 8바이트이다.
1.4 플래그 레지스터 (Flag Register)
프로세서의 현재 상태를 저장하고 있는 레지스터이다. RFLAGS라고 불리는 64비트 크기의 플래그 레지스터가 존재하며, 과거 16비트 플래그 레지스터가 확장된 것이다. 깃발을 올리고, 내리는 행위로 신호를 전달하듯, 플래그 레지스터는 자신을 구성하는 여러 비트들로 CPU의 현재 상태를 표현한다.
RFLAGS는 64비트이며 최대 64개의 플래그를 사용할 수 있지만, 실제로는 아래 그림의 20여개의 비트만 사용한다.
CF(Carry Flag) | 부호 없는 수의 연산 결과가 비트의 범위를 넘을 경우 설정 된다. |
ZF(Zero Flag) | 연산의 결과가 0일 경우 설정 된다. |
SF(Sign Flag) | 연산의 결과가 음수일 경우 설정 된다. |
OF(Overflow Flag) | 부호 있는 수의 연산 결과가 비트 범위를 넘을 경우 설정 된다. |
ex) 3의 값을 갖는 a와 5의 값을 갖는 b가 있을 때, a에서 b를 빼는 연산을 하면, 연산의 결과가 음수 이므로 SF가 설정된다.
CPU는 SF를 통해 a가 b보다 작았음을 알 수 있다.
2. 레지스터 호환
IA-32에서 CPU의 레지스터들은 32비트 크기를 가지며, 이들의 명칭은 각각 eax, ebx, ecx, edx, esi, edi, esp, ebp 였다. 호환성을 위해 이 레지스터들은 x86-64에서도 그대로 사용이 가능하다.
앞에서 작성한 rax, rbx, rcx, rdx, rsi, rdi, rsp, rdp가 이들의 확장된 형태이고, eax, ebx 등은 확장된 레지스터의 하위 32비트를 가리킨다. ex) eax는 rax의 하위 32비트를 말한다.
또한, 과거 16비트 아키텍처인 IA-16과의 호환을 위해 ax, bx, cx, dx, si, di, sp, bp 는 eax, ebx, ecx, edx, esi, edi, esp, edp의 하위 16비트를 가리킨다.
이들 중 몇몇은 다시 상위 8비트, 하위 8비트로 나뉘는데 이들 전체에 대한 내용은 하단의 그림에서 알 수 있다.