[CS:APP/어셈블리] 실수(부동소수점) 숫자를 명령어 안에 직접 적지 못하고 메모리(.rodata) 주소에서 읽어와야 하는 x86-64 아키텍처 이유

자신감·2026년 9월 22일

5주차

목록 보기
6/11

1. 정수와 실수의 컴퓨터 저장 방식 차이

  • 정수 (Integer): 1, 2, 32 같은 숫자는 2진수로 바꾸어 비트에 순서대로 0과 1을 채웁니다.
  • 실수 (Floating Point): 3.14 같은 소수점이 있는 숫자는 컴퓨터에서 부호(1비트), 지수(11비트), 가수(52비트)로 나누어 복잡하게 인코딩하는 IEEE 754 규격을 사용합니다.

2. 정수 연산과 실수 연산의 어셈블리 명령어 차이

정수 연산 어셈블리 명령어는 명령어 자체에 숫자를 바로 적어 넣을 수 있습니다.

addq $32, %rax   # %rax 레지스터에 숫자 32를 더하라 (32가 명령어 코드 안에 직접 들어감)

명령어 바이트 안에 숫자를 직접 넣는 방식을 즉시값 (Immediate value)이라고 부릅니다.

하지만 실수(부동소수점) 연산 명령어는 즉시값을 지원하지 않습니다.

# 문법 에러가 발생하는 불가능한 명령어
vmulsd $3.14, %xmm0, %xmm0  # CPU에 이런 형태의 기계어 형식이 아예 존재하지 않음!

3. 실수를 명령어 안에 직접 적지 못하는 이유

x86-64 CPU를 설계할 때, 64비트 실수(double)의 복잡한 0과 1 비트 패턴을 명령어 코드 안에 직접 집어넣는 하드웨어 회로 규격을 만들지 않았기 때문입니다. 실수 연산 장치(AVX/SSE)는 오직 레지스터끼리 계산하거나 메모리 주소에서 숫자를 읽어와서 계산하도록만 만들어졌습니다.


4. 해결 방법: .rodata 메모리에 실수를 미리 저장해두고 주소로 읽어오기

컴파일러는 C 코드에 적힌 실수 숫자(3.14)를 프로그램의 읽기 전용 데이터 영역(.rodata) 메모리에 미리 8바이트 숫자로 기록해 둡니다.

.section .rodata
.LC0:
    .long 1413754136    # 3.141592... 의 하위 4바이트 정수 표현
    .long 1074340347    # 3.141592... 의 상위 4바이트 정수 표현

.text
    # 메모리 주소 .LC0에서 8바이트를 읽어와서 실수 전용 레지스터 %xmm0에 복사
    vmovsd .LC0(%rip), %xmm0

    # 레지스터에 들어있는 값끼리 곱셈 실행
    vmulsd %xmm0, %xmm1, %xmm0

5. 결론 요약

  • x86-64 CPU의 실수 연산 명령어는 명령어 코드 안에 직접 실수 값을 적는 기능이 없습니다.
  • 따라서 모든 실수 상수는 메모리의 .rodata 영역에 먼저 저장됩니다.
  • CPU는 실행 중에 그 메모리 주소를 찾아가서 레지스터로 값을 읽어온(Load) 뒤에 곱셈이나 덧셈을 수행합니다.
profile
잘할 수밖에 없는 자신감

0개의 댓글