메모리 ↔ 레지스터 ↔ 즉시값(상수) 간 데이터를 복사하는 명령어
모든 조작의 기본 단위
기본 형태
mov[b|w|l|q] S, D ; D <- S
- S : Source operand (어디서 가져올지)
- D : Destination operand (어디다 저장할지)
가능한 조합
| S → D | 허용 여부 | 예시 | 의미 |
|---|---|---|---|
| Immediate → Register | ✅ | movl $0x10, %eax | %eax(32bit)에 0x10을 넣음 |
| Immediate → Memory | ✅ | movb $-1, (%esp) | 메모리 주소(%esp)에 1byte(4bit) -1을 저장 |
| Register → Register | ✅ | movq %rax, %rbx | %rax값을 %rbx에 복사 8bytes(64bit) |
| Register → Memory | ✅ | movq %rax, -12(%rbp) | %rax값을 메모리 주소(%rbp -12)에 복사 |
| Memory → Register | ✅ | movw (%rsp), %ax | 메모리 주소(%rsp)의 값 2bytes(16bit) 을 %ax에 복사 |
| Memory → Memory | ❌ | movq (%rdi), (%rsi) | 메모리 주소(%rdi)의 값 8bytes을 메모리 주소(%rsi)에 복사 (시도) |
movq %rax, %rbx ; 레지스터 → 레지스터
movq (%rdi), %rax ; 메모리 → 레지스터
movq %rax, (%rsi) ; 레지스터 → 메모리
movq $42, %rax ; 상수 → 레지스터
- 메모리 → 메모리 불가, 중간에 레지스터 경유함
; (%rdi) → (%rsi) 불가, %rax 레지스터 경유시키기
movq (%rdi), %rax ; 메모리 → 레지스터
movq %rax, (%rsi) ; 레지스터 → 메모리
| 접미사 | 크기 | 의미 | 형태 | 특징 |
|---|---|---|---|---|
| b | 1 byte | byte | movb → 8 bit | 하위 1바이트 덮음 |
| w | 2 bytes | word | movw → 16 bit | 하위 2바이트 덮음 |
| l | 4 bytes | double word | movl → 32 bit | 레지스터 대상이면 상위 4바이트를 0으로 초기화 |
| q | 8 bytes | quad word | movq → 64 bit | 전체 8바이트 이동 |
| absq | 8 bytes | absolute quad word | movabsq → 64 bit | 64비트 즉시값을 레지스터에 넣는 유일한 명령 |
mov가 목적지 레지스터에 미치는 영향
- movb, movw : 하위 바이트만 바꿈, 상위 값은 그대로 남음
- movl : 상위 4바이트(32비트) 무조건 0
- movq : 8바이트 (64비트) 전체를 바꿈
movl $0x12345678, %eax ; → %rax = 0x0000000012345678
movb $0xFF, %al ; → %rax = 0x00000000123456FF
확장 인스트럭션 (작은 → 큰 레지스터 복사)
Zero-extension (movz)
- 상위 바이트를 0으로 채움
| 명령어 | 의미 |
|---|---|
| movzbw | byte → word |
| movzbl | byte → double word |
| movzwl | word → double word |
| movzbq | byte → quad word |
| movzwq | word → quad word |
| movl(movzlq 없음) | double word → quad word(문법 규칙상 자동) |
Sign-extension (movs)
- 상위 바이트를 부호 비트로 채움
| 명령어 | 의미 |
|---|---|
| movsbw | byte → word |
| movsbl | byte → double word |
| movswl | word → double word |
| movsbq | byte → quad word |
| movswq | word → quad word |
| movslq | double word → quad word |
| cltq | %rax ← sign-extend(%eax) (== movslq %eax, %rax) |
예제
movabsq $0x0011223344556677, %rax
movb $0xAA, %al ; Only changes low byte → 0x00112233445566AA
movsbq %al, %rax ; Sign-extends AA → 0xFFFFFFFFFFFFFFAA
movzbq %al, %rax ; Zero-extends AA → 0x00000000000000AA
정리
- movl → 레지스터일 경우 상위 32비트 0으로 초기화됨 (중요!!!)
- movb, movw는 나머지 바이트에 영향 안 줌 (→ 버그의 씨앗)
- movzXX: Zero-extend, movsXX: Sign-extend
- movabsq: 유일한 64비트 immediate 이동 명령어, 레지스터만 가능
- 메모리 ↔ 메모리 이동은 직접 불가능, 항상 레지스터 경유해야 함
728x90
'CS:APP' 카테고리의 다른 글
| 스택은 사실 아래로 자란다(push,pop) - CS:APP 3.4.4 (0) | 2025.04.07 |
|---|---|
| [C, Assembly] movq 예제 (0) | 2025.04.07 |
| 오퍼랜드 식별자(operand specifier 어셈블리의 시작과 끝 - CS:APP 3.4.1 (0) | 2025.04.07 |
| 레지스터가 뭔데 - CS:APP 3.4 (0) | 2025.04.07 |
| GCC는 C를 어떻게 기계어로 짜깁기할까? - CS:APP 3.2 요약과 인사이트 (0) | 2025.04.07 |