简体   繁体   English

比较Intel x86程序集中的两个数字(nasm)

[英]Compare two numbers in Intel x86 assembly (nasm)

I have the following assembly code: 我有以下汇编代码:

%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 is utility library, which includes program initialization and termination and other functions. rw32.inc是实用程序库,它包括程序初始化和终止等功能。 WriteDouble - prints out st0 on the screen WriteNewLine - just inserts newline. WriteDouble - 在屏幕上打印出st0 WriteNewLine - 只需插入换行符。

and I want this to compare numbers 'a' and 'b' and print the greater one. 我想要比较数字'a'和'b'并打印更大的数字。 My logic is this: get both numbers on stack. 我的逻辑是:在堆栈上得到两个数字。 By fcom set flags. 通过fcom设置标志。 If carry flag is 1, number 'a' is greater, so it needs to be switched with 'b', so it is on top of the stack. 如果进位标志为1,则数字'a'更大,因此需要用'b'切换,因此它位于堆栈顶部。 Otherwise 'b' is greater and just print out result. 否则'b'更大,只打印出结果。

But it seems that program never jumps to label 'greater'. 但似乎该计划从未跳到标签“更大”。 How can this be fixed, please? 请问如何解决这个问题? Thank you. 谢谢。

This why the nice people at Intel gave us fcomi(p) : 这就是为什么英特尔的好人给了我们fcomi(p)

Performs an unordered comparison of the contents of registers ST(0) and ST(i) and sets the status flags ZF, PF, and CF in the EFLAGS register according to the results 对寄存器ST(0)和ST(i)的内容进行无序比较,并根据结果设置EFLAGS寄存器中的状态标志ZF,PF和CF.

The fstsw ax \\ sahf method is ancient, and doesn't even work on all "non-ancient" CPUs (some older x64 processors miss sahf ). fstsw ax \\ sahf方法很古老,甚至不适用于所有“非古老”CPU(一些较旧的x64处理器缺少sahf )。 The use of wait is a sign of truly ancient code, back from the time when dinosaurs still roamed the earth and the FPU was a coprocessor. wait的使用是真正古老代码的标志,从恐龙仍在地球上漫游并且FPU是协处理器的时代开始。

FPU math should never afect to CPU flags like carry and zero! FPU数学应该永远不会影响进位和零等CPU标志!

So copy flags from FPU to CPU flag register after fcomp instruction and than check the carry and zero flags like: 因此,在fcomp指令之后将标志从FPU复制到CPU标志寄存器, fcomp检查进位和零标志,如:

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
...

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

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