繁体   English   中英

ASM8086:mul,imul,进位标志和溢出标志

[英]ASM8086: mul, imul, carry flag and overflow flag

我了解进位标志和溢出标志的逻辑。 但是,当我阅读此程序(写在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] )。 但是,例如,对于第一个,我们使用imul进行(bb)^2

因此我们认为它们是16位带符号数(因此-2^15 <= bb <= 2^15-1 ),并且如果至少有一个和(在乘法算法中)得到,则乘法CF / OF位设置为on CF / OF位打开。

但是由于我们处理带符号的数字,我们不应该检查溢出标志吗?

另外我注意到,由于2^15-1=32767 ,如果我将bb设置为190190^2=36100 ),则CF=0 如果bb等于200200^2=40000 )则CF=1

这是为什么? 有人能详细解释一下吗?

PS:我正在使用EMU8086。

对于IMUL:当中间乘积的有符号整数值与带符号扩展的操作数大小截断的乘积不同时,将设置CF和OF标志,否则将清除CF和OF标志。 对于指令的一种操作数形式,当有效位被送入结果的上半部分时,将设置CF和OF标志,而当结果恰好位于结果的下半部分时,将清除CF和OF标志。 即这些标志在这里几乎相等。 对于SUB:SUB指令执行整数减法。 它评估有符号和无符号整数操作数的结果,并设置OF和CF标志以分别指示有符号或无符号结果中的溢出。 SF标志指示已签名结果的符号。 OF用于签名。 检查指令集参考手册。 即使对于这个旧代码,它仍然是实际的。 但请参阅x86标志

如果您查看IMUL的伪算法,您将看到

IF OperandSize = 16
THEN
  TMP_XP ← AX ∗ SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *)
  DX:AX ← TMP_XP[31:0];
  SF ← TMP_XP[15];
  IF SignExtend(TMP_XP[15:0]) = TMP_XP
    THEN CF ← 0; OF ← 0;
    ELSE CF ← 1; OF ← 1;
  FI;
FI;

CFOF都置位或都清零。 因此,您可以在IMUL之后检查任一标志

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM