问题
I am just getting started with 32-bit assembly and I'm quite confused. I have the following code:
.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
Now from what I understand, I am pushing pi onto the stack then pushing 1 onto the stack, it should compare pi and 1 and see that 1 is lesser and execute a jump. However the comparison doesn't appear to work. Can someone help?
回答1:
Change JL
to JB
, since you can only do unsigned comparisons with the FPU flags.
The reason is that 8087 has only 2 equivalent status bits at the same positions as 8086. Those are CF and ZF. When doing a signed comparison, the processor uses OF state from any preceding operation and the 8087 Busy State as the sign bit.
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 Sets the Control bits C3,C2,C0 according to the conditions
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, the branch codes are implemented as
JL: SF != OF
JB: CF
JBE: CF | ZF
JA: !CF && !ZF
Thus: Behaviourally C3/EQ == Zero and C0/LT == Carry
References: Art of Assembly, FLAGS register, Conditional Jumps
来源:https://stackoverflow.com/questions/16227582/fcom-floating-point-comparison-fails