Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asm相当于一个delphi程序_Delphi_Assembly_X86 64 - Fatal编程技术网

Asm相当于一个delphi程序

Asm相当于一个delphi程序,delphi,assembly,x86-64,Delphi,Assembly,X86 64,我有一个简单的delphi函数,名为SetCompare,它比较两个单值,如果它们不相等,则将一个值设置为另一个值 procedure SetCompare( A : single; B : single ); begin if( A <> B ) then A := B; end; 这样行吗 这样行吗 不,这不起作用,因为浮点比较与二进制比较不同。例如,0和-0具有不同的位模式,但比较时相同。类似地,NaN比较不等于所有值,包括具有相同位模式的NaN

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

procedure SetCompare( A : single; B : single );
  begin
    if( A <> B ) then
      A := B;
  end;
这样行吗

这样行吗

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

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

一些旁白:

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

这样做的目的是什么?你测试过你的代码吗?它有效吗?程序!=功能。你的代码没有任何意义。还请注意,参数在此处按值传递(即传递副本)。对参数所做的任何更改都不会离开该过程。如果您希望发生这种情况,您需要有
var
参数。请获取或模拟的副本。为什么要转换为asm?这是糟糕的Delphi代码(即使您修复了错误),在asm中会更糟糕!退一步想想你在做什么:1)如果A和B不同:你做一个比较和一个作业。2) 如果A和B是相同的:进行比较和跳转。即,两种情况下都有2个操作,但如果您希望A与B相同,只需分配
A:=B是单个操作。因此,您的方法不会带来性能方面的好处-您只会由于未考虑的浮点细节而产生意外行为的可能性。老实说,如果您将一个设置为与另一个相同,如果它们不相同,总是将A设置为B不是更容易吗?在跨平台语言中使用asm是个坏主意。因为这个asm部分只能在x86中工作,而不能在x64、Android(ARM)、MacOS(x64)和iOS(ARM)中工作。这一切都很好,但反汇编通常充满了类似于
MOV EAX、[EBP-$08]
的代码,这些代码根本不容易阅读。要真正习惯这一点并能够阅读这样的代码需要一些时间。@RudyVelthuis和生活中的许多事情一样,需要知识和专业知识。的确如此。但我不认为查看生成的汇编代码对初学者有帮助。这可能会让人困惑。对于初学者来说,一切都会让人困惑。但并不是所有读这篇文章的人都是初学者。我知道我会研究一个或多个编译器发出的代码,然后在这个指导下做进一步的研究。我们的工作也不是教一个完全没有知识或经验的初学者写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;