[Register] 레지스터의 이해
리버싱(Reverse Enginerring)을 하기 위해서는 여러 종류의 많은 지식들을 요구하는데, 중요한것들 중 하나가 바로 레지스터(Register)이다
리버싱을 더욱 잘하기 위해서 레지스터에 대해 이해해보는 시간을 가져보자
- 레지스터란?
레지스터는 CPU가 요청을 처리하는 데 필요한 데이터를 일시적으로 저장하는 기억장치로 우리가 일반적으로 컴퓨터에서 데이터를 영구적으로 저장하기 위해서는 하드디스크(HDD, SSD)가 필요하고 임시적으로 데이터를 저장하는 위치는 메모리(RAM)이라고 알고있다
하지만 메모리로 연산의 결과를 보내고 영구적으로 저장할 데이터를 하드디스크에 저장하는 등의 명령을 처리하기 위해서는 명령에 대한 주소와 종류들을 결정 및 저장 하는 하나의 공간이 더 필요하다 위와 같은 역할을 수행하는것이 바로 레지스터이다
- 32bit / 64bit
일반적으로 우리들의 컴퓨터를 살펴보게 되면 32bit/64bit 로 윈도우 시스템을 설치할것인지 등에 대한 물음이 생길때가 있다 그렇지만 우리가 보통 프로그램을 설치할때는 권장 방식을 이용해서 설치하는 경우가 생기는데
여기서의 32bit/64bit는 CPU의 레지스터가 정보를 처리하는 방식을 의미하는데, 64bit의 윈도우는 32bit의 윈도우 보다 훨씬 많은 양의 RAM을 처리하는데 이를 보면 PC의 자원 중에서 RAM용량이 매우 중요한것과 같은 이치이다
쉽게 생각하면 32bit와 64bit의 차이점은 CPU의 레지스터가 한번에 처리할 수 있는 데이터의 크기로 보면된다
- 레지스터의 데이터 단위
구분 | 설명 |
bit(비트) | 컴퓨터 시스템이 데이터를 연산하거나 표현할 수 있는 제일 기본적인 단위이다 0과 1, 즉 2진수만 표현이 가능하다 |
Byte(바이트) | 바이트는 8개의 비트를 모은것으로 10진수로는 0~255 까지, 16진수로는 0~0xFF까지 표현이 가능하다 |
Word(워드) | 2개의 바이트를 하나로 합치면 워드라고 하면 총 16비트를 의미한다 표현할 수 있는 최대값은 10진수로는 0~65535, 16진수로는 0~0xFFFF까지이다 예전에는 하나의 작업 단위로 많이 사용되었으나, 32비트 시스템으로 넘어오고 나서부터는 잘 사용하지 않는 모습이다 |
DWord(더블워드) | 2개의 워드를 하나로 합치면 더블워드라고 하며 총 32비트를 표현하는 단위이다 10진수는 0~4294967295, 16진수로는 0xFFFFFFFF 까지 표현이 가능하며 32비트 시스템부터는 주소 표현(포인터), 기본 정수 단위로 가장 많이 사용된다 |
KiloByte(킬로바이트) | 1024바이트의 크기를 가진것으로 파일의 단위로 가장 많이 사용된다 |
MegaByte(메가바이트) | 킬로바이트의 제곱의 크기를 가지고있으며, 1048578 바이트로 이루어져있다 이또한 파일의 단위로 가장 많이 사용된다 |
- 레지스터의 주요 용도
구분 | 설명 |
범용 레지스터 | 연산의 중간 결과 저장 연산의 결과 / 함수의 반환값 저장 스택의 시작과 끝 주소 저장 |
명령 포인터 | 다음 실행할 명령어 주소 저장 |
상태 레지스터 | 연산 결과의 상태 저장 |
세그먼트 포인터 | 코드 영역, 데이터 영역의 시작 주소 저장 |
- 레지스터의 종류
x86 레지스터
종류 | 레지스터명 | 설명 및 주요 용도 |
범용 레지스터 | EAX (Accumulator Register) |
산술/논리 연산, 처리 결과 리턴값 저장, 연산, 함수의 반환값 |
EBX (Base Register) |
간접 주소 연산, 데이터에 대한 포인터 | |
ECX (Counter Register) |
카운터, 반복 참조 값, 루프 처리 시 카운터 처리 | |
EDX (Data Register) |
산술/논리 연산 보조, 연산의 중간 결과 | |
ESI (Source index) |
문자열 출발지 주소, 스트링 조작 시 Source 포인터 | |
EDI (Destination index) |
문자열 목적지 주소, 스트링 조작 시 Destination 포인터 | |
ESP (Stack pointer) |
현재 스택 주소, 스택 톱에 대한 포인터, 현재 사용중인 스택(지역변수) 가리키는 포인터 | |
EBP (Base pointer) |
스택 복귀 주소, 스택 베이스에 대한 포인터, 기본 복귀 주소(상위 프로시저의 스택) 용도로도 사용이 가능함 | |
명령 포인터 | EIP (Instruction pointer) |
명령이 실행되는 현재 주소, 다음 실행 할 명령어의 위치를 저장함 |
세그먼트 포인터 |
CS (Code segment) |
코드 세그먼트, 코드 영역 시작 주소 |
DS (Data segment) |
데이터 세그먼트, 데이터 영역 시작 주소 | |
SS (Stack segment) |
스택 세그먼트, 스택 영역 시작 주소 | |
ES (Extra segment) |
데이터 세그먼트, 데이터 영역 시작 주소(추가 데이터 영역의 시작 주소) | |
FS (F segment) |
데이터 세그먼트, 데이터 영역 시작 주소(E 다음 F 세그먼트 사용) | |
GS (G segment) |
데이터 세그먼트, 데이터 영역 시작 주소(F 다음 G 세그먼트 사용) | |
상태 레지스터 (EFLAGS) |
ZF (Zero flag) |
연산 결과가 0일 때 설정, 참 거짓 구분용 |
SF (Sign flag) |
연산 결과가 음수일 때 설정 | |
CF (Carry flag) |
자리 올림, 자리 내림이 발생할 때 설정 | |
OF (Overflow flag) |
정수 허용 범위보다 작거나 클 때 설정 | |
PF (Parity flag) |
연산 결과가 짝수이면 1, 홀수이면 0으로 설정 | |
AF (Auxiliary-carry flag) |
16(8) 비트 연산 시 빌림수(Borrow) 발생 할 경우 1로 설정 |
x64 레지스터
종류 | 레지스터명 | 설명 및 주요 용도 |
범용 레지스터 | RAX (Accumulator register) |
연산, 함수의 반환값 |
RBX (Base register) |
데이터에 대한 포인터 | |
RCX (Counter register) |
루프 처리 시 카운터 처리용 | |
RDX (Data register) |
연산용 | |
RSP (Stack pointer) |
스택 톱에 대한 포인터 | |
RBP (Base pointer) |
스택 베이스에 대한 포인터 | |
RSI (Source index) |
스트링 조작 시 Source 포인터 | |
RDI (Destination index) |
스트링 조작 시 Destination 포인터 | |
추가 범용 레지스터 |
R8 ~ 15 (Register) |
인자 전달 용도 |
XMM0 ~ 15 (SSE2) |
부동 소수점 표현에 사용 |
- 참고
https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
Intel® 64 and IA-32 Architectures Software Developer Manuals
These manuals describe the architecture and programming environment of the Intel® 64 and IA-32 architectures.
www.intel.com
학습중인 내용이기에 오탈자, 틀린 내용 수정 등 피드백은 언제든지 환영입니다 :)