레지스터

Jeonghwan Yoon·2025년 4월 6일

함수 호출 시 사용하는 주요 레지스터들:

종류레지스터설명
인자 전달용%rdi, %rsi, %rdx, %rcx, %r8, %r9첫 6개의 인자 전달 (x86-64 System V 기준)
리턴값%rax함수 결과가 여기에 담김
스택 포인터%rsp현재 스택의 top을 가리킴
프레임 포인터%rbp이전 스택 프레임의 기준점
임시 계산용%rax, %rcx, %rdx, ...연산 중간 저장에 사용
보존용%rbx, %r12~%r15함수 호출 간 값을 유지해야 하는 레지스터들 (callee-saved)

인자 전달 (최대 6개까지 레지스터로)

함수에 인자를 넘길 때는 아래 순서대로 레지스터를 사용해:

인자 번호레지스터
1%rdi
2%rsi
3%rdx
4%rcx
5%r8
6%r9
7번 이상스택에 push 해서 전달함

함수 리턴값은?

  • 리턴값은 기본적으로 %rax에 저장
    • 예: return 42;%rax = 42
  • 리턴값이 128비트 이상이면 다른 레지스터 추가 사용 or 메모리 통한 복잡한 처리 필요

레지스터는 크게 두 종류

구분이름설명
Caller-saved%rax, %rcx, %rdx, %rsi, %rdi, %r8, %r9, %r10, %r11호출한 쪽이 백업해야 함
Callee-saved%rbx, %rsp, %rbp, %r12~%r15호출당한 함수가 백업해야 함 (push, pop)

레지스터 버전별 비교 표

크기이름비트수예시
64비트%rdi, %rax, ...8바이트 (64bit)movq, addq, callq
32비트%edi, %eax, ...4바이트 (32bit)movl, addl
16비트%di, %ax, ...2바이트 (16bit)movw, addw
8비트%dil, %al, ...1바이트 (8bit)movb, addb

%rdi, %edi, %di, %dil을 쓰는 상황

언제어떤 크기?어떤 이름?
long, pointer, 64비트 정수64비트%rdi
int, 32비트 정수32비트%edi
short, 16비트 정수16비트%di
char, 8비트 정수8비트%dil

전달할 값의 크기(자료형)에 따라 자동으로 결정됨.


확장(extension) 계열

  • 작은 크기 → 큰 크기로 바꿀 때 사용
  • 부호(sign)를 유지하느냐에 따라 구분됨
명령어비트 변환
movsblSign-extend byte → long8 → 32비트
movsbqSign-extend byte → quad8 → 64비트
movswlSign-extend word (16) → long (32)16 → 32비트
movswqSign-extend word (16) → quad (64)16 → 64비트
movslqSign-extend long (32) → quad (64)32 → 64비트

명령어비트 변환
movzblZero-extend byte → long8 → 32비트
movzbqZero-extend byte → quad8 → 64비트
movzwlZero-extend word → long16 → 32비트
movzwqZero-extend word → quad16 → 64비트

igned vs unsigned: 정수의 부호(+, -) 유무

종류부호 있음?값의 범위 예 (8비트 기준)
signed (기본)✅ 있음-128 ~ +127
unsigned❌ 없음0 ~ 255

x86-64 아키텍처 규칙

목적명령어결과 값 예
char → int (32bit 부호 확장)movsbl0xFFFFFFFF
char → long (64bit 부호 확장)movsbq0xFFFFFFFFFFFFFFFF
char → long (64bit zero 확장)movzbq0x00000000000000FF

자료형 변환 방향에 따른 동작 요약

방향동작예시 명령어
작은 → 큰 (char → int)확장 필요 (sign/zero extend)movsbl, movzbl
큰 → 작은 (int → char)잘라내기 (하위 비트만 사용)movb %al, (%rsi)
profile
안녕하세요.

0개의 댓글