如何在内联汇编中访问Delphi开放数组参数

4

假设我有一个 Delphi 函数如下:

procedure sortArray(arr: array of DWORD); register;
asm
  //access array here
end;

我应该如何在inline-assembly中访问数组的特定元素?我已经知道arr实际上由两个参数组成:指向数组的指针和它的High(),但我需要确切地知道它是如何工作的。我假设指针在eax中,High值在ebx中,但我不太确定。

procedure sortArray(arr: array of DWORD); register;
asm
  mov DWORD PTR [eax+$4], $09 //set the second element of arr to 9 ???
end;

顺便说一下,如果有人想知道:我使用汇编语言完成这个任务是因为

a) 我想提高我的汇编技能

b) 我需要为学校做这个任务,希望让它变得更加有趣


4
当你使用CPU调试窗口时,你可以自行确定这一点。 - TLama
1
我不是试错学习的忠实拥护者。阅读文档应该是第一步。为什么要求助于逆向工程呢? - David Heffernan
1个回答

7

首先要做的是停止通过值传递数组。对于大数组,这会很低效。而不是按值传递,声明参数为const

然而,由于你的函数名为sortArray,并且由于你的代码试图修改数组,因此更有可能需要一个var参数来获得所需的语义。

procedure sortArray(var arr: array of DWORD);

开放数组的ABI记录在语言指南的程序控制主题中。它说明:

一个开放数组参数作为两个32位值传递。第一个值是数组数据的指针,第二个值是数组元素数量减1。

因此,您的函数与以下函数有效地相同:

procedure sortArray(ArrPtr: PDWORD; ArrHigh: Integer);

接着,您只需要了解调用约定即可,这些都在语言指南的程序控制主题中有所记录:

前三个限定参数按照EAX、EDX和ECX的顺序进行传递。

因此,ArrPtr通过EAX传递,ArrHigh通过EDX传递。


谢谢,但您确定ArrHigh实际上是一个Delphi Integer吗?由于元素数量永远不可能为负,我认为它更可能是一个无符号32位整数,因此是DWORD / CARDINAL。文档没有说明它是否带符号。另外,您能告诉我这行代码是否正确吗?mov DWORD PTR [eax+$4], $09 //将arr的第二个元素设置为9 ??? - Grisu47
1
@Cody227 元素数量永远不能为负数,这是正确的。但是 ArrHigh 不是元素数量,它是最后一个元素的索引。因此,High(arr) = Length(arr)-1。当没有元素时,HighArr 为 -1。所以,是的,第二个参数是有符号的。 - David Heffernan
1
是的,mov DWORD PTR [eax+$4], $09 将会把 $9 赋值给第二个元素。当然,在实际代码中你需要检查是否真的存在第二个元素。 - David Heffernan
2
当然,需要意识到,如果在参数列表中找到 array of X,那么它只能是一个开放数组参数。我写了一篇关于这个的文章(不要介意我打广告):Open array parameters and array of const - Rudy Velthuis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接