컴퓨터의 CPU (1)
메인 메모리를 알아봤으니 다음은 CPU이다.구매한 CPU는 가장 보급, 엔트리 급으로 많이 팔리는 라이젠 7500f이다. 개요CPU는 명령어 처리를 위해 메모리에 저장된 명령어를 읽고(Fetch) 해석하고(Deco
basaeng.tistory.com
이전에는 CPU의 코어에 대해 알아봤으니 이번에는 레지스터에 대해 알아보겠다.
개요
레지스터는 CPU의 설계에 의존한다.
CPU 제조 시에 몇 개를 만들고 어떻게 사용할지 고정된 자원인 것이다.
내가 사용하는 라이젠 7500f의 경우 x86-64 아키텍처로 32비트 기반인 x86의 구조를 유지하며 64비트 기능을 추가한 것이다.
x64는 기능이 많아 비교적 분석할만한 x86을 중점적으로 보겠다.
RISC, CISC
x86은 CISC 구조의 대표적인 예로 x86을 이해하기 위해서 간단하게 RISC, CISC 내용을 간단하게 알고가자.
RISC = Reduced Instruction Set Computer
CISC = Complex Instruction Set Computer
RISC는 명령어의 길이가 고정적이다.
CISC는 명령어의 길이가 가변적이다.
기본적으로 많이들 사용하는 intel, amd의 CPU는 x86-64아키텍쳐이고 이는 CISC기반이다.
위는 내 컴퓨터에서 작성한 코드의 어셈블리 코드 그리고, 명령어이다.
CISC이기 때문에 명령어의 길이가 가변적인 것을 확인할 수 있다.
명령어는 1~15 바이트의 길이를 가질 수 있고, 어셈블리 출력에서 16진수 두 자리가 1바이트를 의미한다. 사진 속에서 띄어쓰기로 구분된 각 16진수 쌍이 하나의 바이트를 나타낸다고 볼 수 있다.
RISC, CISC가 어떤 것이 더 좋고 나쁘다 등의 문제는 내용이 길기 때문에 다른 포스팅에서 적든지 해야겠다.
x86 아키텍처
이제 레지스터를 이해하기 위해 x86 아키텍처에 대해서 알아보자.
x86 아키텍처는 인텔의 8086(당시에는 16비트) 명령어를 기반으로 확장된 아키텍처이다.
따라서 x32보다는 x86로 표기한다.
x86의 레지스터
EAX(Accmulator), EBX(Base)
ECX(Counter), EDX(Data)
ESI, EDI
EBP, ESP
EIP, EFL
를 사용한다.
EIP, ESP는 다른용도로 사용하지 않고, EBP, EFL은 사용한다면 아주 조심해서 사용해야 한다.
나머지 레지스터들은 각각의 특화 용도가있지만 사용자체는 자유롭게 한다.
다만 어떤 어셈블리 명령어들은 특정 레지스터만을 암묵적으로 사용한다.
예를 들어 rep stos dword ptr es:[edi]: 반복(ECX 횟수만큼) EAX 값을 [EDI] 위치부터 시작해 DWORD 단위로 저장하고, EDI 값을 증가시킨다.
좀 더 중요하다고 생각하는 EBP, ESP, EIP에 대해서 더 자세하게 알아보자.
EBP(Base Pointer)
EBP는 현재 스택프레임 범위의 기준이 되는 베이스 레지스터이다.
함수에 진입하는 경우 ebp를 push해줘
돌아갈 과거의 ebp 주소를 기억하게 한다.
ESP(Stack Pointer)
ESP는 현재 stack의 top을 가리키는 레지스터이다.
ESP는 항상 현재 가장 마지막에 push된 값의 위치를 가리킨다. ( ESP는 push가 끝난 후, 새로 저장된 값의 시작 위치를 가리킨다)
(push value를 하면 esp가 감소하고, 해당 위치에 value를 삽입한다.)
x86에서 스택은 아래로 성장한다. (높은 주소 -> 낮은 주소)
함수에 진입할 때 ebp를 sub 명령어를 통해 esp를 감소시켜 해당 함수 범위 내의 지역 변수가 사용할 공간을 확보한다.
지역변수는 ebp-Nh (N은 자연수)를 통해 접근하기 때문에 컴파일 시점에 미리 계산해 사용되는 범위 만큼을 확보한다.
추가적으로 함수를 진입할 때 파라미터는 함수를 호출하는 이전 스택에서 push를 하면서 진입하기 때문에 ebp+Nh를 통해서 파라미터에 접근할 수 있다.
main에서 특정 함수(func라고 하겠다)를 호출하는 경우에 볼 수 있는 메모리 구조를 그림으로 그려봤다.
main 흐름에서 func를 호출하게 된다면, 함수에 파라미터가 있는 경우에는 파라미터를 push하며 esp가 이동하게 되고,
call func를 호출하면, esp가 이동하며 func가 끝난 뒤 원래 흐름으로 돌아올 code영역의 주소를 저장한다.
그리고 func안에서 push ebp -> mov ebp, esp -> sub esp, (함수 stack이 필요한 크기) 를 통해서 해당 함수의 메모리 영역을 확보하는 구조이다.
EIP(Instruction Pointer)
EIP는 현재 CPU가 다음에 실행할 명령어의 주소를 가지고 있다. 이를 통해 코드, 명령의 흐름을 알 수 있다.
직접 수정할 수 없고, call, jmp, ret 등의 명령어를 통해 간접적으로 조작된다.
x86 명령어는 설명하기에는 너무 많기 때문에
https://namu.wiki/w/x86/%EB%AA%85%EB%A0%B9%EC%96%B4%20%EB%AA%A9%EB%A1%9D
x86/명령어 목록
x86 아키텍처의 명령어 목록. AMD64 확장에 대해서는 다루지 않는다. 약어 설명 r : 레지스터 m : 메모리
namu.wiki
킹무위키를 보며 참고하자.
x64 아키텍쳐
intel의 x86을 확장해 AMD가 만든 64비트 아키텍쳐이다.
기존의 8개의 레지스터는 각각의 역할이 어느정도 있기 때문에 그냥 사용할 수 있는 r8~r15레지스터가 추가되었다.
그리고 ax->eax가 된것처럼 rax, rbx 등의 이름을 사용한다.
기존의 _cdecl, _stdcall과 다르게 x64는 앞의 4개의 인자는 레지스터에 저장한다. (RCX, RDX, R8, R9)
나머지는 스택에 왼->오 순서로 저장된다.
대부분 함수는 인자가 4개 이하이기 때문에 이러한 설계는 성능에 도움이 된다.
나머지는 나중에 더 적든지 해야겠다.
'CS > CA, OS' 카테고리의 다른 글
컴퓨터의 CPU (3) - 캐시 메모리 (1) | 2025.05.10 |
---|---|
컴퓨터의 시간측정 (0) | 2025.04.29 |
컴퓨터의 프로세스 (0) | 2025.04.05 |
컴퓨터의 CPU (1) (0) | 2025.01.20 |
컴퓨터의 RAM (0) | 2024.12.26 |