我有以下汇编代码:
%include 'rw32.inc'
[segment .data use32]
a dd 2.0
b dd 1.0
[segment .code use32]
prologue ; macro -- inicialization
fld dword [a]
fld dword [b]
fcom
jc greater
jmp less
greater:
fxch
less:
call WriteDouble
call WriteNewLine
epilogue ; macro -- termination
rw32.inc是实用程序库,它包括程序初始化和终止等功能。 WriteDouble - 在屏幕上打印出st0 WriteNewLine - 只需插入换行符。
我想要比较数字'a'和'b'并打印更大的数字。 我的逻辑是:在堆栈上得到两个数字。通过fcom设置标志。如果进位标志为1,则数字'a'更大,因此需要用'b'切换,因此它位于堆栈顶部。否则'b'更大,只打印出结果。
但似乎程序永远不会跳到标签'更大'。 请问如何解决这个问题? 谢谢。
答案 0 :(得分:2)
这就是为什么英特尔的好人给了我们fcomi(p)
:
执行寄存器ST(0)和ST(i)的内容的无序比较,并设置状态标志ZF,PF和 根据结果,EFLAGS寄存器中的CF
fstsw ax \ sahf
方法很古老,甚至不适用于所有“非古代”CPU(一些较旧的x64处理器错过sahf
)。使用wait
是真正古老代码的标志,从恐龙仍在地球上漫游并且FPU是协处理器的时代开始。
答案 1 :(得分:1)
因此,在fcomp
指令之后将标志从FPU复制到CPU标志寄存器,然后检查进位和零标志,如:
fld qword ptr [a]
fcomp qword ptr [b]
wait ;wait FPU
fstsw ax ;copy FPU flags to ax
sahf ;copy ax to CPU flags
jbe LessOrEqu ;do less or equal
...