在Delphi中asm过程结束时要恢复哪些CPU寄存器
在汇编代码中编写Delphi过程或函数时,哪些寄存器必须保存并在过程结束时恢复为原始值 当从(内联)汇编代码调用另一个Delphi过程或函数时,我可以期望其他函数对寄存器做什么?哪些寄存器将恢复为其原始值,哪些不恢复 (显然,这两个问题的答案相同)在Delphi中asm过程结束时要恢复哪些CPU寄存器,delphi,assembly,cpu-registers,basm,Delphi,Assembly,Cpu Registers,Basm,在汇编代码中编写Delphi过程或函数时,哪些寄存器必须保存并在过程结束时恢复为原始值 当从(内联)汇编代码调用另一个Delphi过程或函数时,我可以期望其他函数对寄存器做什么?哪些寄存器将恢复为其原始值,哪些不恢复 (显然,这两个问题的答案相同) 我假设是德尔福。我知道,EAX用于32位返回值。查看SysUtils.pas中的asm代码,似乎EBX、ESI和EDI被推送并恢复,但其他的都没有。但是,我找不到任何关于此的文档。我不知道这些文档是否是最新的,但您应该看看Embarcardero W
我假设是德尔福。我知道,
EAX
用于32位返回值。查看SysUtils.pas中的asm代码,似乎EBX
、ESI
和EDI
被推送并恢复,但其他的都没有。但是,我找不到任何关于此的文档。我不知道这些文档是否是最新的,但您应该看看Embarcardero Wiki:
引述:
通常,asm语句中寄存器的使用规则与外部过程或函数的使用规则相同。asm语句必须保留EDI、ESI、ESP、EBP和EBX寄存器,但可以自由修改EAX、ECX和EDX寄存器。在进入asm语句时,EBP指向当前堆栈帧,ESP指向堆栈顶部。除了ESP和EBP之外,asm语句不能假设语句项上的寄存器内容
函数的前三个参数分别在
EAX
、EDX
和ECX
中给出。附加参数被推送到堆栈上。对于对象的方法,Self
指针始终是(不可见的)第一个参数。结果应该在EAX
中。对于返回长字符串的函数,函数的(不可见)最后一个参数是指向结果字符串的指针(它本身就是指向字符串第一个字符的指针)
EBX
不得更改(除非您在程序/功能结束前将其还原),也不得ESP
、EBP
、ESI
或EDI
。这里有一篇关于Delphi内联ASM的精彩介绍:这是正确的信息。如果结果是Int64,则它位于EAX/EDX耦合中。实际上,寄存器中的内容取决于调用约定。没有任何东西禁止编写“stdcall”和“cdecl”汇编函数,它们不使用寄存器传递参数。寄存器中的内容、堆栈中的内容(以及FPU寄存器中的内容)取决于参数类型。EBX、ESI、EDI可以在过程内部更改,只要它们正确保存和恢复即可。当然,触摸EBP和ESP要危险得多。@Idsandon:True,但OP写了“我假设Delphi的默认[register]调用约定”。@Rejbrand:记住“Real、方法指针、variant、Int64和结构化类型不符合寄存器参数的条件”。因此,即使您使用默认的调用约定,您在EAX、ECX和EDX中找到的内容仍然取决于参数类型。@Idsandon:我没有提供任何错误信息;我只是没有写关于非简单数据类型的所有细节。我指定的寄存器是默认的,与简单类型(整数和友元)一起使用。(在我找到这些信息之前,我已经找了很久了,所以我只是想帮忙。)但当然,非简单类型稍微复杂一些。例如,几乎不言而喻的是,任意记录不适合32位寄存器。但是我的信息仍然有用,因为指向记录的指针适合这样的寄存器。你是不是想成为我…?谢谢你的链接,尽管它已经断了(URL中缺少一个右括号)。@Servaas:你没有看到上面的右括号吗?:)问题是StackOverflow(或者,实际上,MarkDown)无法解释包含右括号的URL(自然)。显然,链接已经修复。谢谢你,罗伯·肯尼迪。啊,好吧,我不知道。我是StackOverflow的新手:)。我会记住的。