사용 개념: 산술 연산과 상태 플래그의 ZF, SF, CF, OF.
“명령 뒤의 결과와 플래그를 쓰라”는 문제는 같은 하위목표의 되풀이다. ① 결과: 16진수로 계산하고 칸의 크기에 맞게 자른다 ② ZF: 자른 결과가 0인가 ③ SF: 자른 결과의 맨 윗자리 비트 ④ CF: 두 피연산자를 부호 없는 수로 읽어 참값이 범위 밖인가(덧셈은 넘음, 뺄셈은 작은 수에서 큰 수를 뺌) ⑤ OF: 두 피연산자를 부호 있는 수로 읽어 참값이 범위 밖인가. MOV는 플래그를 바꾸지 않고, INC와 DEC는 CF만 그대로 둔다1.
8비트의 범위는 부호 없이 0~255, 부호 있게 −128~127이다. 16비트는 0~65,535와 −32,768~32,767이다.
문제 1 · 완전한 풀이
mov al,7Fh
add al,1 ; (가)
sub al,1 ; (나)
(가)
- 결과: 7Fh + 01h = 80h. 8비트에 들어간다. AL = 80h.
- ZF: 80h는 0이 아니다. ZF = 0.
- SF: 80h =
10000000. 맨 윗자리 비트가 1이다. SF = 1. - CF: 부호 없이 127 + 1 = 128. 0~255 안이다. CF = 0.
- OF: 부호 있게 127 + 1 = 128. −128~127 밖이다. OF = 1.
(나)
- 결과: 80h − 01h = 7Fh. AL = 7Fh.
- ZF: 0이 아니다. ZF = 0.
- SF: 7Fh =
01111111. SF = 0. - CF: 부호 없이 128 − 1 = 127. 큰 수에서 작은 수를 뺐다. CF = 0.
- OF: 부호 있게 −128 − 1 = −129. 범위 밖이다. OF = 1.
AL은 처음 값 7Fh로 돌아왔지만 OF는 두 번 다 켜졌다. 부호 있는 수로 보면 127에서 −128로 건너뛰었다가 다시 건너온 것이다.
문제 2 · 마지막 하위목표만 빈칸
mov al,80h
add al,92h
- 결과: 80h + 92h = 112h. 8비트로 자르면 12h. AL = 12h.
- ZF: 0.
- SF: 12h =
00010010. SF = 0. - CF: 부호 없이 128 + 146 = 274. 255를 넘었다. CF = 1.
- OF: __
답
OF = 1. 80h는 −128, 92h는 −110이다. −128 + (−110) = −238로 −128~127 밖이다. 음수 둘을 더했는데 결과 12h(18)가 양수로 나온 것으로도 알 수 있다.
문제 3 · 하위목표 절반이 빈칸
mov bh,6Ch
add bh,95h ; (가)
mov al,2
sub al,3 ; (나)
(가)
- 결과: 6Ch + 95h = 101h → BH = 01h.
- ZF: __
- SF: 0.
- CF: __
- OF: __
(나)
- 결과: __
- ZF: 0.
- SF: __
- CF: __
- OF: 0. 부호 있게 2 − 3 = −1로 범위 안이다.
답
(가) ZF = 0(결과 01h는 0이 아니다). CF = 1(부호 없이 108 + 149 = 257, 255를 넘었다). OF = 0(부호 있게 108 + (−107) = 1, 범위 안이다. 부호가 다른 두 수의 합은 넘치지 않는다).
(나) 결과: 02h − 03h는 0 아래로 내려가 FFh다. SF = 1(FFh의 맨 윗자리 비트). CF = 1(부호 없이 2 − 3, 작은 수에서 큰 수를 뺐다).
문제 4 · 독립 문제
표시한 줄마다 결과와 ZF, SF, CF, OF를 쓰라.
mov ax,0FFFFh
add ax,1 ; (가)
inc ax ; (나)
mov cl,80h
sub cl,1 ; (다)
sub cl,80h ; (라)
답
| 줄 | 결과 | ZF | SF | CF | OF |
|---|---|---|---|---|---|
| (가) | AX = 0000h | 1 | 0 | 1 | 0 |
| (나) | AX = 0001h | 0 | 0 | 1 | 0 |
| (다) | CL = 7Fh | 0 | 0 | 0 | 1 |
| (라) | CL = FFh | 0 | 1 | 1 | 1 |
(가) 16비트에서 FFFFh + 1 = 10000h → 0000h. 부호 없이 65,535 + 1은 범위 밖, 부호 있게 −1 + 1 = 0은 범위 안.
(나) INC는 CF를 바꾸지 않는다. (가)의 1이 남아 있다. 0 + 1에서 올림이 없으니 0이라고 답하기 쉽다.
(다) 80h − 1 = 7Fh. 부호 없이 128 − 1은 범위 안, 부호 있게 −128 − 1 = −129는 범위 밖.
(라) 7Fh − 80h. 부호 없이 127 − 128은 작은 수에서 큰 수를 빼므로 CF = 1, 결과 FFh. 부호 있게 127 − (−128) = 255는 범위 밖이라 OF = 1. 두 플래그가 함께 켜진다.
-
INC가 CF를 바꾸지 않는다는 것은 Intel 64 and IA-32 Architectures Software Developer’s Manual, Volume 2의 INC 항목에 있다. 답은 파이썬 흉내로 확인했다. 실제 CPU로 돌린 결과가 아니다. ↩