본문 바로가기
시스템해킹

Syetem Hacking - [02] Computer Science - (2) Computer Architecture

by minpiter 2022. 12. 1.
반응형

CONTENTS

 

1. 컴퓨터 구조
 1-1. 컴퓨터 구조의 세부 분야

 1-2. 폰 노이만 구조
 1-3. 명령어 집합 구조

2. x86-64 아키덱처
 2-1. x86-64 아키덱처 : 범용/세그먼트/명령어 포인트 레지스터
 2-2. x86-64 아키덱처 : 플래그 레지스터
 2-3. x86-64 아키덱처 : 레지스터 호환

3. 요약 정리

 

 

 


 

 

 

 

1. 컴퓨터 구조(Computer Architecture)

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

  - 컴퓨터의 기능 구조에 대한 설계, 명령어 집합구조, 마이크로 아키텍처, 그리고 기타 하드웨어 및 컴퓨터 방법에 대한 설계 등이 포함


컴퓨터 기능 구조에 대한 설계
  - 컴퓨터가 연산을 효율적으로 하기 위해 어떤 기능들이 컴퓨터에 필요한지 고민하고, 설계하는 분야
  - 대표적으로 폰 노이만 구조, 하버드 구조, 수정된 하버드 구조

명령어 집합구조(Instruction Set Architecture)
  - CPU의 명령어에 대한 설계로, CPU가 처리해야하는 명령어를 설계하는 분야
  - 대표적으로 ARM, MIPS, AVR, 인텔의 x86 및 x86-64
마이크로 아키텍처(Micro Architecture)
  - CPU의 하드웨어적 설계
  - 정의된 명령어 집합을 효율적으로 처리할 수 있도록 CPU의 회로를 설계하는 분야

 


 

 1-1. 컴퓨터 구조의 세부 분야

 

  ● 기능 구조의 설계

    - 폰 노이만 구조

    - 하버드 구조

    - 수정된 하버드 구조

 

  ● 명령어 집합구조

    - x86, x86-64

    - ARM

    - MIPS

    - AVR

 

  ● 마이크로 아키텍처

    - 캐시 설계

    - 파이프라이닝

    - 슈퍼 스칼라

    - 분기 예측

    - 비순차적 명령어 처리

 

  ● 하드웨어 및 컴퓨팅 방법론

    - 직접 메모리 접근

 


 

 

 1-2. 폰 노이만 구조

폰 노이만 구조

 

  - 폰 노이만 구조 : 연산과 제어를 위해 ①중앙처리장치를, 저장을 위해 ②기억장치를 사용, 그리고 장치간에 데이터나 제어 신호를 교환할 수 있도록 ③버스라는 전자 통로를 사용

 

  ① 중앙처리장치(Central Processing Unit, CPU)

    - CPU는 프로그램의 연산을 처리하고 시스템을 관리하는 컴퓨터의 두뇌  

    - CPU는 산술/논리 연산을 처리하는 산술논리장치(Arithmetic Logic Unit, ALU)와 CPU를 제어하는 제어장치(Control Unit), CPU에 필요한 데이터를 저장하는 레지스터(Register) 등으로 구성

 

  ② 기억장치(Memory)

    - 컴퓨터가 동작하는데 필요한 여러 데이터를 저장하기 위해 사용되며, 용도에 따라 주기억장치와 보조기억장치로 분류

    - 주기억장치는 프로그램 실행과정에서 필요한 데이터들을 임시로 저장하기 위해 사용되며,

      대표적으로 램(Random-Access Memory, RAM)이 있다

    - 보조기억장치는 운여체제, 프로그램 등과 같은 데이터를 장기간 보관할 때 사용되며,

      대표적으로 하드 드라이브(Hard Disk Drive, HDD), SSD(Solid State Drive)가 있다

 

  ③ 버스(Bus)

    - 컴퓨터 부품과 부품 사이 또는 컴퓨터와 컴퓨터 사이에 신호를 전송하는 통로

    - 데이터가 이동하는 데이터 버스(Data Bus), 주소를 지정하는 주소 버스(Address Bus), 읽기/쓰기를 제어하는 제어 버스(Control Bus)가 있다

    - 이외에도 랜선이나 데이터 전송 소프트웨어, 프로토콜 등도 버스라고 불린다.

 


 

※ 기억장치가 있는데 CPU 안에 레지스터가 필요한 이유


  ▷ CPU가 필요한 데이터를 빠르게 공급하고, 반출할 수 있어야 효율을 제대로 발휘

  ▷ CPU의 연산속도가 기억장치와의 데이터 교환속도보다 압도적으로 빠르기 때문에, 기억장치만을 사용하면 병목현상 발생
  ▷ 따라서, CPU는 교환속도를 획기적으로 단축하기 위해 레지스터와 캐시라는 저장장치를 내장

 

 


 

 

 1-3. 명령어 집합 구조 (Instruction Set Architecture, ISA)

  - CPU가 해석하는 명령어의 집합을 의미

  - ISA는 IA-32, x86-64(x64), MIPS, AVR 등으로 분류

  

  1) x86-64

    - 고성능 프로세서를 설계하기 위해 사용

    - 많은 전력을 소모하며, 발열도 상대적으로 심하므로

      안정적으로 전력을 공급할 수 있고, 냉각 장칠르 구비하는데 공간상의 부담이 크지 않은 데스크톱 또는 랩톱에 적합

    - 아키텍처 중 인텔의 x86기반 CPU 점유율이 가장 높다

   

   2) ARM, MIPS, AVR

    - 전력 소모와 발열이 적은 임베디드 장비에 사용

    - 드론과 같이 배터리를 사용하거나 공유기, 인공지능 스피커와 스마트폰과 같은 장비

 

 

 

 


 

 

 

 

2. x86-64 아키텍처

  - 인텔의 32비트 CPU 아키텍처인 IA-32를 64비트 환경에서 사용할 수 있도록 확장

 

 1) n 비트 아키텍처

  - '64비트 아키텍처'의 64 또는 32는 CPU가 한번에 처리할 수 있는 데이터의 크기를 의미

    (=CPU가 이해할 수 있는 데이터의 단위라는 의미에서 WORD라고 부름)

  - 32비트 아키텍처의 CPU가 제공할 수 있는 가상메모리의 크기가 작기 때문에 64비트 아키텍처 사용

  - 32비트 아키텍처 : 4,294,967,296바이트(=4기가 바이트)

    64비트 아키텍처 : 16엑사 바이트(=16,777,216 테라바이트)

 


 

 2-1. x86-64 아키텍처 : 범용/세그먼트/명령어 포인트 레지스터

 

  1) x86-64 아키텍처 : 레지스터

    - 레지스터는 CPU가 데이터를 빠르게 저장하고 사용할 때 이용하는 보관소

    - 산술 연산에 필요한 데이터를 저장하거나 주소를 저장하고 참조하는 등 다양한 용도로 사용

    - x64 아키텍처에는 범용 레지스터(General Register), 세그먼트 레지스터(Segment Register),

      명령어 포인터 레지스터(Instruction Pointer Register, IP), 플래그 레지스터(Flag Register)

 

   2) 범용 레지스터

    - x86-64에서 각각의 범용 레지스터는 8바이트를 저장

    - 자주 쓰이는 범용 레지스터들의 주용도는 아래와 같다

이름 주용도
rax (accumulator 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) 스택의 바닥을 가리키는 포인터

 

  3) 세그먼트 레지스터

   - x64 아키텍처에는 cs, ss, ds, es, fs, gs 총 6가지 세그먼트 레지스터가 존재하며, 각 레지스터 크기는 16비트

   - x64에서 cs, ds, ss 레지스터는 코드 영역과 데이터, 스택 메모리 영역을 가리킬 때 사용되고,

     나머지 레지스터는 운영체제 별로 용도를 결정할 수 있도록 범용적인 용도로 제작된 세그먼트 레지스터

 

  4) 명령어 포인터 레지스터

   - CPU가 어느 부분의 코드를 실행할지 가리키는게 명령어 포인터 레지스터의 역할

   - x64 아키텍처의 명령어 레지스터는 rip이며, 크기는 8바이트

 


 

 2-2. x86-64 아키텍처 : 플래그 레지스터

   - 프로세서의 현재 상태를 저장하고 있는 레지스터

   - x64 아키텍처에서는 RFLAGS라고 불리는 64비트 크기의 플래그 레지스터가 존재

   - 깃발을 올리고, 내리는 행위로 신호를 전달하듯, 플래그 레지스터는 자신을 구성하는 여러 비트들로 CPU의

     현재 상태를 표현

   - RFLAGS 분류는 아래와 같다

플래그 의미
CF(Carry Flag) 부호 없는 수의 연산 결과가 비트의 범위를 넘을 경우 설정 됩니다.
ZF(Zero Flag) 연산의 결과가 0일 경우 설정 됩니다.
SF(Sign Flag) 연산의 결과가 음수일 경우 설정 됩니다.
OF(Overflow Flag) 부호 있는 수의 연산 결과가 비트 범위를 넘을 경우 설정 됩니다.

 

 

  ▷ 플래그 사용 예시

    - 3의 값을 갖는 a와 5의 값을 갖는 b가 있을 때,

      a에서 b를 빼는 연산을 하면, 연산의 결과가 음수이므로 SF가 설정된다.

      따라서, CPU는 SF를 통해 a가 b보다 작았음을 알 수 있다.

 


 

 2-3. x86-64 아키텍처 : 레지스터 호환

  - x86-64 아키텍처는 IA-32의 64비트 확장 아키텍처이며, 호환 가능

  - IA-32 : 32비트 크기의 레지스트 소유 eax, ebx, ecx, edx,esi,edi, esp, ebp

  - x86-64 : 64비트 크기의 레지스트 소유 rax, rbx, rcx,rdx, rsi, rdi, rsp, rbp 

x86-64의 레지스터

 

 

 

 


 

 

 

 

3. 요약 정리

  • 범용 레지스터(General Register) : 주 용도는 있으나, 그 외의 용도로도 자유롭게 사용할 수 있는 레지스터. x64에서는 rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp, r8-r15가 있다.
  • 세그먼트 레지스터(Segment Register) : 과거에는 메모리 세그멘테이션이나, 가용 메모리 공간의 확장을 위해 사용됐으나, 현재는 주로 메모리 보호를 위해 사용되는 레지스터 x64에는 cs, ss, ds, es, fs, gs가 있다.
  • 플래그 레지스터(Flasg Register) : CPU의 상태를 저장하는 레지스터
  • 명령어 포인터 레지스터(Instruction Pointer Register, IP) : CPU가 실행해야할 코드를 가리키는 레지스터. x64에서는 rip가 있다.

 

 

 


 

 

 

※ rax, eax, ax, ah, al 비교

rax: 0x0123456789abcdef      // 64비트
eax:         0x89abcdef      // 32비트
ax :             0xcdef      // 16비트
ah :             0xcd        // ax의 상위 8비트
al :               0xef      // ax의 하위 8비트

 

 

 

 

 

 

 

 

 

 

 

 

※ 본 게시글은 DREAMHACK 강의를 참조하여 작성하였습니다.

반응형