발자취

[Reverse Engineering] #03. 컴퓨터 구조와 명령어 집합 구조 본문

Dreamhack Study/Reverse Engineering

[Reverse Engineering] #03. 컴퓨터 구조와 명령어 집합 구조

해린 2024. 5. 29. 00:11

본 게시물은 Dreamhack의 Reverse Engineering 로드맵 과정을 학습한 기록이다.

 

 

#01. 서론

1. 컴퓨터 구조란?

: 컴퓨터가 효율적으로 작동할 수 있도록 하드웨어 및 소프트웨어의 기능을 고안, 구성하는 방법

 

▶ 다음과 같은 것들이 포함됨

- 컴퓨터의 기능 구조에 대한 설계: 컴퓨터가 연산을 효율적으로 하기 위해 필요한 컴퓨터 기능 고민, 설계

                                                      (대표적인 예: 폰 노이만 구조, 하버드 구조, 수정된 하버드 구조)

- 명령어 집합구조: CPU가 처리해야하는 명령어 설계

- 마이크로 아키텍처: 정의된 명령어 집합을 효율적으로 처리할 수 있게 CPU 회로 설계

- 기타 하드웨어 및 컴퓨팅 방법에 대한 설계

 

 

1. 컴퓨터 기능 구조의 설계

: 컴퓨터가 연산을 효율적으로 하기 위해 필요한 컴퓨터 기능 고민, 설계

  • 폰 노이만 구조
  • 하버드 구조
  • 수정된 하버드 구조

 

2. 명령어 집합구조

: CPU가 처리해야하는 명령어 설계

  • x86, x86-64
  • ARM
  • MIPS
  • AVR

 

3. 마이크로 아키텍처

: 정의된 명령어 집합을 효율적으로 처리할 수 있게 CPU 회로 설계

  • 캐시 설계
  • 파이프라이닝
  • 슈퍼 스칼라
  • 분기 예측
  • 비순차적 명령어 처리

 

4. 하드웨어 및 컴퓨팅 방법론

  • 직접 메모리 접근

 

#02. 폰 노이만 구조

폰 노이만의 컴퓨터 세 가지 핵심 기능: 연산, 제어, 저징

  • 중앙처리장치(CPU): 연산, 제어
    • 산술논리장치(ALU): 산술/논리 연산 처리
    • 제어장치(Control Unit): CPU에 필요한 데이터를 저장하는 레지스터

 

  • 기억장치(memory): 저장
    • 주기억장치: 프로그램 실행과정에서 필요한 데이터 임시 저장 (예: RAM)
    • 보조기억장치: 운영체제, 프로그램 등과 같은 데이터를 장기간 보관 (예: HDD, SSD)

 

  • 버스(bus): 장치간에 데이터나 제어 신호 교환
    • 데이터 버스(Data Bus): 데이터 이동
    • 주소 버스(Address Bus): 주소 지정
    • 제어 버스(Control Bus): 읽기/쓰기 제어

 

 

폰 노이만 구조

 

 

#03. 명령어 집합 구조

: CPU가 해석하는 명령어의 집합

  • ISA는 IA-32 , x86-64(x64), MIPS, AVR 등 다양하게 존재
    • 모든 컴퓨터가 동일 수준의 연산 능력을 요구하지 않고 컴퓨팅 환경이 다양
    • x86-64 아키텍처의 점유율이 압도적으로 많다

 

#03-1. x86-64 아키텍처 (== amd64) 란?

1. WORD란?

: CPU가 이해할 수 있는 데이터의 단위

  • 예: 32비트 아키텍처: 32비트 데이터까지만 처리 가능 (ALU는 32비트까지 계산 가능, 레지스터 용량 및 버스 대역폭 32비트)

2. WORD가 크면 좋은 점

: 가용한 메모리 자원이 충분해서 소프트웨어의 최고 성능을 낼 수 있음

 

 

#03-2. x86-64 아키텍처: 레지스터

: CPU 내부의 저장장치, CPU가 빠르게 접근 가능

  • 산술 연산에 필요한 데이터 저장
  • 주소 저장, 참조

 

1. 범용 레지스터

: 주용도 외의 용도로도 사용될 수 있는 레지스터. 각 범용 레지스터는 8바이트 저장 가능

이름 주용도
rax 함수의 반환 값
rbx X
rcx (counter register) 반복문의 반복 횟수
rdx (data register) X
rsi (source index) 데이터를 옮길 때 원본을 가리키는 포인터
rdi (destination index) 데이터를 옮길 때 목적지를 가리키는 포인터
rsp (stack pointer) 사용중인 스택의 위치를 가리키는 포인터
rbp (stack base pointer) 스택의 바닥을 가리키는 포인터

 

 

2. 세그먼트 레지스터 (cs, ss, ds, es, fs, gs)

: 코드 영역과 데이터, 스택 메모리 영역을 가리킴

 

3. 명령어 포인터 레지스터 (rip)

: 실행할 코드를 가리킴

 

4. 플래그 레지스터

: 프로세서의 현재 상태 저장

플래그 의미
CF (Carry Flag) 부호 없는 수의 연산 결과가 비트의 범위를 넘음
ZF (Zero Flag) 연산 결과가 0
SF (Sign Flag) 연산 결과가 음수
OF (Overflow Flag) 부호 있는 수의 연산 결과가 비트의 범위를 넘음

 

 

 

x86-64의 레지스터

 

 


#04. Quiz

Q1. rax = 0x0123456789abcdef 일 때, al의 값은?

  1. 0x01
  2. 0xef
  3. 0x02
  4. 0xcd

답: 2

 

 

Q2. rax에서 rbx를 뺐을 때, ZF가 설정되었다. rax와 rbx의 대소를 비교하시오.

  1. >
  2. <
  3. ==

답: 3

해설: ZF은 연산 결과가 0일 때 설정되는 플래그 레지스터이다.

 

 

Q3. rax = 0x0123456789abcdef 일 때, ax의 값은?

  1. 0x4567
  2. 0xcdef
  3. 0x0123
  4. 0x89ab

답: 2

 

 

Q4. rax = 0x0123456789abcdef 일 때, ah의 값은?

  1. 0x02
  2. 0xef
  3. 0xcd
  4. 0x01

답: 3

 

 

Q5. rax = 0x0123456789abcdef 일 때, eax의 값은?

  1. 0x89abcdef
  2. 0x3456789a
  3. 0xefcdab89
  4. 0x01234567

답: 1