我理解了进位标志和溢出标志的逻辑。但是,当我读到这个程序(写在 MASM 8086 中)时,我有点困惑。
程序的目的是判断一个二次方程是否有两个不同的解、两个相等的解或根本没有解。
.model small
.stack
.data
aa dw 2
bb dw 4
cc dw 2
sol_msg db "There exist two real solutions", CR, NL
no_sol_msg db "No real solutions! ", CR, NL
sol_coinc db "The two solutions coincide! ", CR, NL
.code
.startup
mov ax, bb
imul bb
jc overflow ; I decided to work at most with 16-bit numbers
push ax
mov ax, aa
imul cc
jc overflow
mov bx, 4
imul bx
jc overflow
pop bx
sub bx, ax
jo overflow
js mess2
jz mess3
lea si, sol_msg
jmp next
mess2: lea si, no_sol_msg
jmp next
mess3: lea si, sol_coinc
next: mov bx, LUNG_MSG
mov ah, 2
loop1: mov dl, [si]
INT 21h
inc si
dec bx
jnz loop1
jmp end1
overflow:
nop
end1:
.exit
end
现在,我的疑问是:为什么前三个检查已经测试了进位标志,而最后一个检查了溢出标志?
由于在最后一个中,我们在两个有符号数字之间进行减法(正如我们所认为的那样),我们必须检查溢出标志以查看是否存在溢出(即数字是否超出区间[-2^15,2^15-1]
)。但是对于第一个,例如,我们(bb)^2
使用imul
.
所以我们认为它们是 16 位有符号数(so -2^15 <= bb <= 2^15-1
),并且如果至少一个和(在乘法算法中)打开 / 位,则乘法将/CF
位打开。OF
CF
OF
但是既然我们处理有符号数,我们不应该检查溢出标志吗?
我还注意到,因为,2^15-1=32767
如果我设置bb
为190
( 190^2=36100
) CF=0
如果bb
等于200
( 200^2=40000
) CF=1
。
这是为什么?有人可以详细解释一下吗?
PS:我用的是EMU8086。