1

我刚刚开始使用 32 位汇编,我很困惑。我有以下代码:

.586
.MODEL FLAT

.STACK 4096

.DATA

.CODE
main PROC

finit
fldpi
fld1
fcom
fstsw ax
sahf
JL jumper

nop

jumper:
nop

nop
main ENDP
END

现在据我了解,我将 pi 推入堆栈然后将 1 推入堆栈,它应该比较 pi 和 1 并看到 1 较小并执行跳转。但是,这种比较似乎不起作用。有人可以帮忙吗?

4

1 回答 1

5

更改JLJB,因为您只能对 FPU 标志进行无符号比较。

原因是 8087 只有 2 个与 8086 相同位置的等效状态位。它们是 CF 和 ZF。在进行有符号比较时,处理器使用任何先前操作的 OF 状态和 8087 忙碌状态作为符号位。

 8087:   [Busy] [ EQ ] [ Top of Stack Ptr ] [UND] [SOF] [ LT ]
                  C3                         C2     C1    C0    <-- C3..C0
 8086:   [Sign] [Zero] [ 0  ] [ AF ] [  0 ] [PF ] [ 1 ] [  C ]

FCOMx 根据条件设置控制位 C3、C2、C0

 C3 = EQ == equal
 C2 = Undefined == Set if ST or Mem is undefined
 C1 = Marks either Underflow or Overflow of FP Stack (If Overflow Exception == TRUE)
 C0 = True, if ST(i) < ST(1)/Mem

OTOH,分支代码实现为

    JL:   SF != OF
    JB:   CF
    JBE:  CF | ZF
    JA:   !CF && !ZF

因此:行为上 C3/EQ == 零和 C0/LT == 进位

参考:组装艺术标志寄存器条件跳转

于 2013-04-26T03:46:28.647 回答