gpt4 book ai didi

delphi - 删除用纯汇编编写的函数的序言

转载 作者:行者123 更新时间:2023-12-03 14:49:44 29 4
gpt4 key购买 nike

我使用的是 Delphi 2010。是否可以告诉 Delphi 不要为函数生成序言?我正在编写一些像这样的纯汇编函数:

procedure SomeAssembly; stdcall;
begin
asm
...
end;
end;

我想告诉 Delphi 不要为这个函数生成序言和尾声,就像 C++ 的 __declspec(naked) 功能。

所以没有人浪费时间,我不需要帮助让这些函数与序言一起工作;我已经可以做到了。这不仅带来很大的不便,而且会给维护带来巨大的麻烦。我必须手动检查编译器生成的序言以查看它们的长度,如果发生变化,我的程序就会崩溃。

我也知道我可以将函数编写为字节数组中的一系列字节,但这比必须查找 Delphi 序言的长度还要糟糕。

最佳答案

Delphi 不会为没有参数且使用注册调用约定声明的函数生成序言或尾声。如果您想要没有序言的函数,请将它们声明为零参数、寄存器调用约定函数。另外,跳过 begin-end block 并直接进入汇编。

procedure SomeAssembly; // register; (implied)
asm
// ...
end;

由于您实际上对函数的性质撒了谎,因此调用它们可能会很棘手。如果您实现了一个函数,就像它接收参数并使用不同的调用约定一样,那么您必须确保编译器在调用站点知道这一点。为此,请声明一个函数指针,该指针反射(reflect)函数的“真实”类型而不是声明的类型。例如,如果您的函数实际上是一个双参数 stdcall 函数,请声明如下内容:

type
TSomeAssemblyFunc = function (Arg1: Integer; Arg2: PAnsiChar): Boolean; stdcall;
var
SomeAssemblyProc: TSomeAssemblyProc;

现在,分配该变量,使其指向您的函数:

SomeAssemblyProc := TSomeAssemblyProc(@SomeAssembly);
if SomeAssembly(2, 'foo') then ...

除了跳过序言和尾声之外,编译器还会为此函数生成不正确的 RET 指令(因为调用约定不同),因此您必须确保说 ret 8 在您的代码中,而不是让编译器的默认 ret 指令发生。

<小时/>

如果您有一个可用的调试器,那么查找 Delphi 序言的长度是微不足道的:

  1. 在函数开始处设置断点。
  2. 调用该函数。
  3. 当调试器在断点处停止时,切换到 CPU View 。
  4. 查看构成序言的说明。
  5. 计算这些指令旁边显示的字节数。

关于delphi - 删除用纯汇编编写的函数的序言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5450841/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com