使用指针将代码转换为 Pascal 中的程序集 - Delphi
我下面有这段代码,我想将其转换为 ASM,以便也在 Delphi 中使用。
var
FunctionAddressList: Array of Integer;
type TFunction = function(parameter: Integer): Integer; cdecl;
function Function(parameter: Integer): Integer;
var
ExternFunction: TFunction;
begin
ExternFunction := TFunction(FunctionAddressList[5]);
Result := ExternFunction(parameter);
end;
它工作正常,但是当我尝试它的汇编版本时:
function Function(parameter: Integer): Integer; cdecl;
asm
mov eax, FunctionAddressList
jmp dword ptr [eax + 5 * 4]
end;
它应该工作,因为在 C++ 中它以两种方式工作:
void *FunctionAddressList;
_declspec(naked) int Function(int parameter)
{
_asm mov eax, FunctionAddressList;
_asm jmp dword ptr [eax + 5 * 4];
}
typedef int (*TFunction)(int parameter);
int Function(int parameter)
{
TFunction ExternFunction = ((TFunction *)FunctionAddressList)[5];
return ExternFunction(parameter);
}
但它在 Delphi 中不起作用。
在 Assembly 版本中,它将数组乘以 4,因为它是数组每个元素之间的偏移大小,因此两个版本是等效的。
所以,我想知道为什么它不适用于Delphi。在Delphi中,数组中整数值之间的偏移量与C++不同?
我已经尝试过许多偏移量,如 1、2、4、6、8 等。以及许多类型的数组(指针数组;仅指针;整数数组等),并且我尝试了许多调用约定, cdecl 是唯一适用于非 asm 版本的,但使用 ASM 时,所有测试都不起作用。
谢谢。
I have this code below, and I want to translate it to ASM, to use in Delphi too.
var
FunctionAddressList: Array of Integer;
type TFunction = function(parameter: Integer): Integer; cdecl;
function Function(parameter: Integer): Integer;
var
ExternFunction: TFunction;
begin
ExternFunction := TFunction(FunctionAddressList[5]);
Result := ExternFunction(parameter);
end;
It works normaly, but when I try its Assembly version:
function Function(parameter: Integer): Integer; cdecl;
asm
mov eax, FunctionAddressList
jmp dword ptr [eax + 5 * 4]
end;
It is supposed to work, because, in C++ it works in both ways:
void *FunctionAddressList;
_declspec(naked) int Function(int parameter)
{
_asm mov eax, FunctionAddressList;
_asm jmp dword ptr [eax + 5 * 4];
}
typedef int (*TFunction)(int parameter);
int Function(int parameter)
{
TFunction ExternFunction = ((TFunction *)FunctionAddressList)[5];
return ExternFunction(parameter);
}
But it doesn't work in Delphi.
In the Assembly version, it multiplies the array to 4, because it's the offset size between each element of the array, so both versions are equivalent.
So, I want to know why it doesn't work with Delphi. In Delphi, the offset size between Integer values in a array is different than C++?
I've already tried many offsets, as 1, 2, 4, 6, 8, etc. And many types of Array (Array of Pointer; only Pointer; Array of Integer, etc), and I've tried many calling conventions, and cdecl was the only that worked with the non-asm version, but with ASM, all the tests didn't work.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一个测试应用程序重现错误:
Bar地址定义正确,但问题是Delphi编译器为Foo生成序言和结尾,所以真正的Foo代码是
结果堆栈损坏,参数错误,Bar返回地址是错误的。如果您仍然想完成这个技巧,请使用
First test app to reproduce error:
The Bar address is defined correctly, but the problem is that Delphi compiler generates prologue and epilog for Foo, so real Foo code is
As a result the stack is corrupted, the parameter is wrong and Bar return address is wrong. If you still want to do the trick, use
整数数组
并不是你想象的那样。它是一个自动管理的动态数组。您应该使用
FunctionAddressList: ^Pointer;
尝试相同的操作 - 但请注意,您必须进行手动分配和释放。Array of Integer
is not what you think it is. It's an automatically managed dynamic array.You should try the same using
FunctionAddressList: ^Pointer;
-- note however that you will have to do manual allocation and deallocation.