사용 개념: OFFSET과 PTR 연산자, 리틀 엔디언.

“PTR로 읽은 값을 쓰라”는 문제는 같은 하위목표의 되풀이다. ① 펼치기: 변수를 정의한 순서대로 메모리 바이트로 펼친다(2바이트 이상인 값은 아랫자리 바이트부터) ② 시작 자리: 이름의 자리에 더한 수만큼 뒤로 간다 ③ 집기: PTR 앞에 적은 크기만큼 바이트를 집는다 ④ 붙이기: 높은 주소의 바이트가 윗자리가 되게 붙인다1.

검증: 네 문제의 메모리 바이트와 레지스터 값. 파이썬 흉내로 확인 — 21_ptr-little-endian-ladder_p4.py

문제 1 · 완전한 풀이

.data
varB BYTE 65h,31h,02h,05h
varW WORD 6543h,1202h
varD DWORD 12345678h
.code
mov ax,WORD PTR [varB+2]     ; a.
mov bl,BYTE PTR varD         ; b.
mov bl,BYTE PTR [varW+2]     ; c.
mov ax,WORD PTR [varD+2]     ; d.
mov eax,DWORD PTR varW       ; e.
  1. 펼치기: varB가 오프셋 0에서 시작한다고 하자.
오프셋   0   1   2   3   4   5   6   7   8   9   10  11
바이트   65  31  02  05  43  65  02  12  78  56  34  12
        └── varB ───┘  └── varW ───┘  └─── varD ────┘
  1. a. 시작 자리 varB+2 = 오프셋 2. 두 바이트 02 05를 집는다. 높은 주소의 05가 윗자리다. AX = 0502h.
  2. b. 시작 자리 varD = 오프셋 8. 한 바이트 78. BL = 78h.
  3. c. 시작 자리 varW+2 = 오프셋 6. 한 바이트 02. BL = 02h.
  4. d. 시작 자리 varD+2 = 오프셋 10. 두 바이트 34 12. AX = 1234h.
  5. e. 시작 자리 varW = 오프셋 4. 네 바이트 43 65 02 12를 집어 거꾸로 붙인다. EAX = 12026543h.

문제 2 · 마지막 하위목표만 빈칸

.data
myBytes BYTE 12h,34h,56h,78h
.code
mov ax,WORD PTR [myBytes+1]
  1. 펼치기: 12 34 56 78. 바이트 배열이라 적은 순서 그대로다.
  2. 시작 자리: myBytes+1 = 오프셋 1.
  3. 집기: 두 바이트 34 56.
  4. 붙이기: AX = __
답

AX = 5634h. 높은 주소(오프셋 2)의 56이 윗자리, 낮은 주소(오프셋 1)의 34가 아랫자리다. 집은 순서대로 3456h라고 쓰면 틀린다.

문제 3 · 하위목표 절반이 빈칸

.data
nums WORD 0A1B2h,0C3D4h
big  DWORD 0DEADBEEFh
.code
mov al,BYTE PTR [nums+1]     ; a.
mov eax,DWORD PTR nums       ; b.
mov ax,WORD PTR [big+1]      ; c.
  1. 펼치기: __
  2. a. 시작 자리 오프셋 1. 집기와 붙이기: __
  3. b. 시작 자리 오프셋 0. 네 바이트를 집는다. 붙이기: __
  4. c. 시작 자리: __ 집기와 붙이기: __
답
  1. B2 A1 D4 C3 EF BE AD DE. nums가 오프셋 0~3, big이 오프셋 4~7이다.
  2. 한 바이트 A1. AL = A1h. 첫 워드 A1B2h의 윗바이트다.
  3. B2 A1 D4 C3을 거꾸로 붙여 EAX = C3D4A1B2h. 뒤의 원소가 윗자리로 간다.
  4. big은 오프셋 4에서 시작하므로 big+1 = 오프셋 5. 두 바이트 BE AD. AX = ADBEh.

문제 4 · 독립 문제

다음을 차례로 실행한다. (가)를 실행한 뒤의 메모리 8바이트와 (나), (다), (라)의 레지스터 값을 쓰라.

.data
val DWORD 11223344h
arr BYTE 0AAh,0BBh,0CCh,0DDh
.code
mov WORD PTR [val+1],0FFEEh   ; (가)
mov eax,val                   ; (나)
mov bx,WORD PTR [val+3]       ; (다)
mov ecx,DWORD PTR arr         ; (라)
답

처음 메모리: 44 33 22 11 AA BB CC DD.
(가) 오프셋 1과 2에 FFEEh를 아랫자리 바이트부터 적는다. 메모리: 44 EE FF 11 AA BB CC DD.
(나) EAX = 11FFEE44h. 가운데 두 바이트만 바뀌었다.
(다) 오프셋 3부터 두 바이트 11 AA. BX = AA11h. val의 마지막 바이트와 arr의 첫 바이트가 붙었다. 변수의 끝을 넘어 읽어도 오류가 아니다.
(라) AA BB CC DD를 거꾸로 붙여 ECX = DDCCBBAAh.

  1. 답은 파이썬 흉내로 확인했다. 실제 어셈블러로 돌린 결과가 아니다. ↩