티스토리 뷰
서로 다른 부품이 모여서 '컴퓨터'라는 하나의 기계로서 작동할 수 있습니다 이를 컴퓨터 구조(Computer Architecture) 라고 부릅니다
CPU가 사용하는 명령어와 관련된 설계를 명령어 집합구조 (Instruction Set Architecture, ISA)라고 함
가장 유명하고 많이 사용되는 ISA가 x86-64 아키텍쳐
컴퓨터가 연산을 효율적으로 하기 위해 어떤 기능들이 컴퓨터에 필요한지 고민하고, 설계하는 분야입니다. 대표적으로 폰노이만 구조, 하버드 구조, 수정된 하버드 구조가 있습니다.
명령어 집합구조에는 ARM, MIPS, AVR, x86 및 x86-64 등이 있습니다.
CPU의 하드웨어적 설계는 마이크로 아키텍쳐(Micro Architecture)라고 부름
현대적 컴퓨터의 기능 구조에 큰 영향을 끼쳤다고 평가받는 폰 노이만 구조와 명령어 집합 구조 중 x86-64 알아봄
폰 노이만 구조
연산, 제어, 저장의 세 가지 핵심 기능
제어를 위해 중앙처리장치(Central Processing Unit, CPU), 저장을 위해 기억장치(memory) 사용함, 장치간에 데이터나 제어 신호를 교환할 수 있게 버스(bus)라는 전자 통로 사용함
- 중앙처리장치
CPU의 연산을 처리하고 시스템을 제어하는 컴퓨터의 두뇌. 산술/논리 연산을 처리하는 산술논리자잋(Arithmetic Logic Unit, ALU)와 CPU를 제어하는 제어장치(Control Unit), CPU에 필요한 데이터를 저장하는 레지스터(Register) 등으로 구성됨
- 기억장치
용도에 따라 주기억장치와 보조기억장치로 분류됨. 주기억장치는 프로그램 실행과정에서 필요한 데이터들을 임시로 저장하기 위해 사용됨 대표적으롬 램(Random-Access Memory, RAM)이 있습니다. 보조기억장치는 운영 체제, 프로그램 등과 같은 데이터를 장기간 보관하고자 할때 사용됨, 대표적으로 하드 드라이브(Hard DIsk Drive, HDD), SSD(Solid State Drive)
- 버스
컴퓨터 부품과 부품 사이 또는 컴퓨터와 컴퓨터 사이에 신호를 전송하는 통로를 말함. 데이터가 이동하는 데이터 버스(Data Bus), 주소를 지정하는 주소 버스(Address Bus), 읽기/쓰기를 제어하는 제어 버스(Control Bus)가 있음. 이 외에 랜선이나 데이터 전송을 목적으로 하는 소프트웨어, 프로토콜 등도 버스라고 불림
1999년, AMD는 인텔의 32비트 CPU 아키텍처인 IA-32를 64비틀로 확장한 AMD64 아키텍처를 발표하였습니다. 이후 범용적이고 중립적으로 지칭되는 x86-64라는 명칭이 탄생하게 되었습니다.
- n 비트 아키텍처
'64비트 아키텍처', '32비트 아키텍처' 에서 64와 32는 CPU가 한번에 처리할 수 있는 데이터의 크기입니다. CPU가 이해할 수 있는 데이터의 단위라는 의미 에서 WORD 라고 부릅니다
- WORD가 크면 유리한점
32비트 아키텍처의 CPU가 제공할 수 있는 가상메모리의 크기가 작기때문, 32비트 아키텍처에서는 4,294,967,296바이트(=4기가 바이트)가 최대임, 반면 64비트 아키텍처에서는 이론상 16엑서 바이트(=16,777,216 테라바이트)의 가상메모리를 제공. 이는 웬만해서 완정한 사용이 불가능 할 정도로 큰 크기임
레지스터
레지스터는 CPU 내부의 저장장티로, 산술 연산에 필요한 데이터를 저장하거나 주소를 저장하고 참조하는 등 다영한 용도로 사용됨, x64 아키텍처에는 범용 레지스터(General Register), 세그먼트 레지스터(Segment Register), 명령어 포인터 레지스터(Instruction Pointer Register, IP), 플래그 레지스터(Flag Register)가 존재합니다.
= 범용 레지스터
범용 레지스터는 주용도는 있으나, 그 외 임의의 용도로도 사용할 수 있음. x86-64에서 각각의 범용 레지스터는 8바이트를 저장할 수 있고, 부호 없는 정수를 기준으로 2^64 - 1 까지 나타낼 수 있습니ㅏㄷ.
| 이름 | 주용도 |
| rax (accmulator register) | 함수의 반환 값 |
| rbx (base register) | x64에서는 주된 용도 없음 |
| rcx (counter register) | 반복문의 반복 횟수, 각종 연산의 시행 횟수 |
| rdx (data register) | x64에서는 주된 용도 없음 |
| rsi (source index) | 데이터를 옮길 떄 원본을 가리키는 포인터 |
| rdi (destination index) | 데이터를 옮길 떄 목적지를 가리키는 포인터 |
| rsp (stack pointer) | 사용중인 스택인 위치를 가리키는 포인터 |
| rbp (stack base pointer) | 스택의 바닥을 가리키니는 포인터 |
= 세그먼트 레지스터
x64 아키텍처에는 cs, ss, ds, es, fs, gs 총 6가지 세그먼트 레지스터가 존재하며, 각 레지스터의 크기는 16비트입니다. 세그먼트 레지스터는 x64로 아키텍처가 확장되면서 용도에 큰 변화가 생긴 레지스터입니다.
과거 IA-32, IA-16에서는 세그먼트 레지스터를 이용하여 사용 가능한 물리 메모리의 크기를 키울려고 했습니다. 예를 들어 IA-16에서는, 어떤 주소를 cs:offset라고 한다면, 실제로 cs<<4 + offset의 주소를 사용하여 16비트 범위에서 접근할 수 없는 주소에 접그날 수 있었습니다. 당시에는 범용 레지스터의 크기가 작아서 사용 가능한 메모리의 주소 폭이 좁았지만, x64에서는 넓기때매 이런 용도로는 사용되지 않습니다.
현대의 x64에서 cs, ds, ss 레지스터는 코드 영역과 데이터, 스택 메모리 영역을 가리킬 떄 사용되고 나머지는 운영체제가 용도를 결정 할 수 있습니다
= 명령어 포인터 레지스터
기계어로 작성되어있는 코드에서 CPU가 어느 부분의 코드를 실행할지 가리키는게 명령어 포인터 레지스터의 역할입니다. x64 아키텍처의 명령어 레지스터는 rip이며, 크기는 8바이트입니다.
= 플래그 레지스터
플래그 레지스터는 프로세서의 현재 상태를 저장하고 있는 레지스터입니다. x64 아키텍처에서는 과거 16비트 에서 64비트로 확장된 RFLAGS라고 불리는 플래그 레지스터가 존재합니다.
RFLAGS는 64비트이므로 64개의 플래그를 사용할 수 있지만, 일반적으로 20여개의 비트만 사용됩니다. 대표적인 플래그는 위 와 같습니다.
| 플래그 | 의미 |
| CF (Carry Flag) | 부호 없는 수의 연산 결과가 비트의 범위를 넘을 경우 설정 됩니다. |
| ZF (Zero Flag) | 연산의 결과가 0일 경우 설정 됩니다. |
| SF (Sign Flag) | 연산의 결과가 음수일 경우 설정 됩니다. |
| OF (Overflow Flag) | 부호 있는 수의 연산 결과가 비트 범위를 넘을 경우 설정 됩니다. |
= 레지스터 호환
x86-64 아키텍처는 IA-32의 64비트 확정 아키텍처이며, IA-32에서 CPU의 레지스터들은 32비트 크기를 가지며, 이들의 명칭은 eax, ebx, ecx, edx, esi, edi, esp, ebp였습니다.
rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp가 이들의 확장 형태이며, eax, ebx등은 확장된 레지스터의 하위 32비트를 가르킵니다.
ex) eax는 rax의 하위 32비트를 의미합니다.
또한 16비트 아키텍처 IA-16과의 호환을 위해 ax, bc, cx, dx, si, di, sp, bp는 eax, ebx등의 하위 16비트를 가르킵니다.
또한 8비트 아키텍처과의 호환을 위해 ah, al, bh, bl, ch, cl , dh, dl는 ax, bx등의 하위 4비트를 2개로 쪼개 2비트를 가르킵니다
ex) ah, al은 ax의 하위 4비트를 각각 2비트씩 가르킵니다
'개발 > 해킹' 카테고리의 다른 글
| 리버스 엔지니어링 (3) (0) | 2024.01.29 |
|---|---|
| 리버스 엔지니어링 (1) (0) | 2024.01.19 |
| 리눅스 명령어 정리 (0) | 2024.01.14 |
- Total
- Today
- Yesterday