1. 레지스터와 데이터 크기
- x86-64 시스템의 범용 레지스터는 64비트 크기
- 레지스터는 하위 크기로도 접근 가능:
%al (8비트), %ax (16비트), %eax (32비트), %rax (64비트)
2. 데이터 형식과 메모리 저장
- 데이터 이동 명령어:
movb, movw, movl, movq는 각각 1, 2, 4, 8바이트 처리
3. 제로 확장(Zero Extension)과 부호 확장(Sign Extension)
- 작은 크기의 데이터를 큰 레지스터에 넣을 때:
movz : 제로 확장 (빈 자리를 0으로 채움)
movs : 부호 확장 (부호 비트를 복사하여 채움)
- 예시:
movzbl : 1바이트 → 4바이트, 0으로 확장
movsbl : 1바이트 → 4바이트, 부호 유지하며 확장
4. 주의할 점
movl 명령어는 목적지 레지스터의 상위 32비트를 자동으로 0으로 설정
- 반면,
movb, movw는 상위 비트를 변경하지 않음
📌 확장 명령어란?
- 작은 크기의 데이터를 더 큰 크기의 레지스터에 저장할 때, 남는 공간을 어떻게 채울지를 지정하는 명령어
- 종류:
movzXx: Zero-extend (제로 확장)
movsXx: Sign-extend (부호 확장)
예시
- 메모리 값:
0xF0 (1바이트, -16)
movzbl → 00000000 00000000 00000000 11110000 → +240
movsbl → 11111111 11111111 11111111 11110000 → -16
🎯 퀴즈 (사용자 풀이 포함)
Q1. 다음 중 부호 확장을 하는 명령어는?
Q2. 메모리에서 -16(0xF0)을 부호 유지하며 %rbx에 저장하려면?
- 정답: B)
movsbl (%rax), %ebx ✅
Q3. movzbl (%rax), %ebx 실행 시, %rax가 가리키는 값이 0x80일 때 %ebx는?
- 정답: A) 00000000 00000000 00000000 10000000 (128) ❌
Q4. 언제 movsbl을 사용해야 할까?
💡 실제 사용 예시 (C 코드)
char c = -16;
int x = c + 5;
c는 1바이트 → 연산 시 4바이트로 확장되어야 함
- 이때 부호를 유지하려면
movsbl 같은 명령어가 필요함
📈 흐름도 요약
- 작은 데이터를 큰 레지스터에 넣을 때:
- 이 데이터가 signed인가 unsigned인가?
- signed →
movs
- unsigned →
movz
🔚 정리
- 확장 명령어는 작지만 중요한 개념으로, 연산의 정확성을 좌우함
- Zero/Sign 확장은 연산 전 데이터 크기를 맞추는 데 꼭 필요함
- 처음에는 어렵지만, 퀴즈와 흐름도, 실제 예제를 통해 체득 가능함