컴퓨터 구조와 명령어 집합구조, 인텔의 x86-64에 대한 내용 정리이다.
컴퓨터 구조 중에서 CPU가 사용하는 명령어와 관련된 설계를 명령어 집합구조(Instruction Set Architecture)라고 한다.
가장 널리 사용하는 ISA 중 하나가 인텔의 x86-64 아키텍처이다.
컴퓨터 구조와 명령어 집합 구조
Computer Architecture란 컴퓨터가 효율적으로 작동할 수 있도록 하드웨어 및 소프트웨어의 기능을 고안하고, 이들을 구성하는 방법이다. 컴퓨터 구조는 컴퓨터의 기능 구조에 대한 설계, 명령어 집합구조, 마이크로 아키텍처, 그리고 기타 하드웨어 및 컴퓨팅 방법에 대한 설계 등이 포함된다.
컴퓨터의 기능구조에 대한 설계란 컴퓨터가 연산을 효율적으로 하기 위해 어떤 기능들이 컴퓨터에 필요한지 고민하고, 설계하는 분야이다. (ex. 폰 노이만, 하이버, 수정된 하버드)
CPU의 명령어에 대한설계는 명령어 집합구조(ISA)라고 불리며, CPU가 처리해야하는 명령어를 설계하는 분야 이다.
(ex. ARM, MIPS, AVR, x86-64 등)
CPU의 하드웨어적 설계는 Micro Architecture라고 불리며, 정의된 명령어 집합을 효율적으로 처리할 수 있도록, CPU의 회로를 설계하는 분야이다.
폰 노이만 구조
과거 폰 노이만 과학자는 컴퓨터에 연산, 제어, 저장의 세 가지 핵심 기능이 필요하다고 생각했다. 근대의 컴퓨터는 연산과 제어를 위한 CPU, 저장을 위한 Memory, 그리고 장치간의 데이터나 제어 신호를 교환할 수 있는 bus라는 전자 통로를 사용한다.
CPU는 산술/논리 연산을 처리하는 산술논리장치(ALU)와 CPU를 제어하는 CU(Control Unit), CPU에 필요한 데이터를 저장한느 레지스터(Register) 등으로 구성한다.
기억자치는 데이터를 저장하기 위해 사용된다. 용도에 따라 주기엊ㄱ장치와 보조기억장치로 분류 된다.
주기억장치는 프로그램 실행과정에서 필요한 데이터들을 임시로 저장하기 위해 사용된다.(ex. RAM)
보조기억장치는 운영 체제, 프로그램 등과 같은 데이터를 장기간 보관하고자 할때 사용된다.(ex. Hard Disk Drive)
버스는 컴퓨터 부품과 부품 사이 또는 컴퓨터와 컴퓨터 사이에 신호를 전송하는 통로를 말한다.
데이터가 이동하는 Data Bus와 주소를 지정하는 Address Bus, 읽기/쓰기를 제어하는 Control Bus가 있다.
랜선이나 데이터 전송 소프트웨어, 프로토콜 등도 버스라고 부른다
명령어 집합 구조(Instruction Set Architecture)
ISA란 CPU가 해석하는 명령어의 집합을 의미한다. 기계어로 이루어져 있고, 프로그램을 실행하며 CPU가 이 명령어들을 읽고, 처리한다.
ISA는 종류가 다양한데, 모든 컴퓨터가 동일한 수준의 연산 능력을 요구하지 않고, 컴퓨팅 환경이 다양하기 때문에 그렇다.
인텔의 x86-64는 고성능 프로세서를 설계하기 위해 사용되고, 이를 기반한 CPU들은 많은 전력을 소모하며 비교적 발열도 심하다.
x86-64 아키텍처
n 비트 아키테처의 n은 CPU가 한번에 처리할 수 있는 데이터의 크기이다. 컴퓨터 과학에서는 CPU가 이해할 수 있는 데이터의 단위라는 의미에서 WORD라고 부른다. 32비트 아키텍처에서는 ALU는 32비트까지 계산할 수 있으며, 레지스터의 용량 및 각종 버스들의 대역폭이 32비트이다.
CPU가 프로세스에게 제공하는 가상의 메모리 공간을 가상메모리라 한다. WORD가 크면, 예를 들어, 64비트 아키텍처에서는 이론상 16엑사 바이트(=15,777,216 테라바이트)의 가상 메모리를 제공할 수 있다. 32비트 아키텍처는 4기가 바이트가 최대 제공 메모리인 반해 완전한 사용이 불가능할 정도로 큰 크기이기때문에 WORD가 클 수록 유리하다
x86-64 아키텍처의 레지스터
레지스터는 CPU가 데이터를 빠르게 저장하고 사용할 때 이용하는 보관소이며, 산술 연산에 필요한 데이터를 저장하거나 주소를 저장하고 참조하는 등 다양한 용도로 사용된다.
x64 아키텍처에는 범용 레지스터, 세그먼트 레지스터, 명령어 포인터 레지스터, 플래그 레지스터가 존재한다.
범용 레지스터
주용도 외에 다양한 용도로도 사용가능한 레지스터이다. 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) | 스택의 바닥을 가리키는 포인터 |
자주 사용하는 범용 레지스터이다.
세그먼트 레지스터
x64 아키텍처에는 cs, ss, ds, es, fs, gs총 6가징세그먼트 레지스터가 존재하며 각 레지스터의 크기는 16비트이다.
현대의 x64에서 cs, ds, ss는 코드 영역과 데이터 ,스택 메모리 영역을 가리킬 때 사용되고, 나머지 레지스터는 운영체제 별로 용도를 결정할 수 있도록 범용적인 용도로 제작된 세그먼트 레지스터 이다.
명령어 포인터 레지스터
프로그램은 일련의 기계어 코드들로 이루어져 있습니다. 이 중에서 CPU가 어느 부분의 코드를 실행할지 가리키는게 명령어 포인터 레지스터의 역할 이다. x64 아키텍처의 명령어 레지스터는 rip이며, 크기는 8바이트 이다.
플래그 레지스터
프로세서의 현재 상태를 저장하고 있는 레지스터이다. x64 아키텍처에서는 RFLAGS라고 불리는 64비트 크기의 플래그 레지스터가 존재한다. 플래그 레지스터는 자신을 구성하는 여러 비트들로 CPU의 현재 상태를 표현한다.
RFLAGS는 64비트이므로 최대 64개의 플래그를 사용할수 있다. 밑은 주로 접하는 플래그들이다.
CF(Carry Flag) | 부호 없는 수의 연산 결과가 비트의 범위를 넘을 경우 설정 됩니다. |
ZF(Zero Flag) | 연산의 결과가 0일 경우 설정 됩니다. |
SF(Sign Flag) | 연산의 결과가 음수일 경우 설정 됩니다. |
OF(Overflow Flag) | 부호 있는 수의 연산 결과가 비트 범위를 넘을 경우 설정 됩니다. |
+추가
rax는 64비트 기준
eax는 32비트
ax는 16비트
ah,al는 8비트
ah(high)는 ax의 상위 8비트
al(low)는 ax의 하위 8비트
rax: 0x0123456789abcdef
eax: 0x89abcdef
ax : 0xcdef
ah : 0xcd
al : 0xef