Asm等同于delphi程序

Gro*_*rMD -5 delphi assembly x86-64

我有一个名为SetCompare的简单delphi函数,它比较两个单例,如果它们不相等,则将一个值设置为另一个.

procedure SetCompare( A : single; B : single );
  begin
    if( A <> B ) then
      A := B;
  end;
Run Code Online (Sandbox Code Playgroud)

我试图将其转换为asm:

procedure SetCompare( A : Single; B : Single ); register;
  begin
    asm
      mov EAX,A
      mov ECX,B
      cmp EAX,ECX
      jne SetValue

      @SetValue:
      mov EAX,ECX
    end;
  end;
Run Code Online (Sandbox Code Playgroud)

这会有用吗?

Dav*_*nan 8

这会有用吗?

不,这不起作用,因为浮点比较与二进制比较不同.例如0,-0具有不同的位模式,但比较相同.类似地,NaN比较不等于所有值,包括NaN具有相同位模式的值.

解决如何编写代码的最简单方法是让编译器编译Pascal代码,并检查生成的汇编代码.

一些旁白:

  • 无论如何,你的功能毫无意义,因为它没有返回值,也没有副作用.
  • 如果性能足以编写汇编程序,那么您应该编写纯汇编函数,而不是asmPascal函数中的内联块.在任何情况下,x64编译器都不支持.
  • 你的参数已经存在于寄存器中,因此将它们复制到其他寄存器是没有意义的.对于x86代码,A到达EAXB进入EDX.鉴于EAX已经包含A,为什么要将其复制到EAX?它已经存在了.而B已经在EDX,为什么把它复制到ECX?对于x64代码,这两个参数在浮点寄存器中传递,并且可以直接在那里进行比较.一旦开始编写汇编程序,就需要了解调用约定的寄存器使用.
  • jne的意义毫无意义.如果执行没有跳转,那么它将移动到下一行代码.你跳到哪里去了.

  • 对于初学者来说,一切都会让人感到困惑.但并非每个读这篇文章的人都是初学者.我知道我会研究一个或多个编译器发出的代码,然后以此为指导进行进一步的研究.在没有知识或经验的情况下教一个完整的初学者来编写asm,如何做到这一点也不是我们的工作.那太多了. (2认同)