如何运用Delphi的Visual C寄存器调用约定实现函数调用的长尾?

2026-04-10 19:372阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计396个文字,预计阅读时间需要2分钟。

如何运用Delphi的Visual C寄存器调用约定实现函数调用的长尾?

我有一个用Visual C++ 2012编写的程序,我尝试调用用Delphi编写的函数(我没有源代码)。这是Visual C++中的代码:cppint _fastcall(test)(void*)=(int(_fastcall(*)(void*))0x00489A7D);test((void*)0x12345678);但在编译时遇到了问题。

我有一个用Visual C 2012编写的程序,我试图调用用Delphi编写的函数(我没有源代码).这是Visual C中的代码:

如何运用Delphi的Visual C寄存器调用约定实现函数调用的长尾?

int (_fastcall *test)(void*) = (int(_fastcall *)(void*))0x00489A7D; test((void *)0x12345678);

但在编译的代码中它实际上是:

.text:1000113B mov eax, 489A7Dh .text:10001140 mov ecx, 12345678h .text:10001145 call eax

我除外的是:

.text:1000113B mov ebx, 489A7Dh .text:10001140 mov eax, 12345678h .text:10001145 call ebx

我知道’fastcall’使用EAX,ECX,EDX作为参数,但我不知道为什么Visual C编译器使用EAX作为入口点. EAX不应该是第一个参数(12345678h)吗?

我试图在汇编代码中调用delphi函数并且它可以工作,但我真的想知道如何在不使用汇编的情况下执行此操作.

那么可以让Visual C编译器生成代码,就像我说的那样吗?如果是的话,怎么做?

在x86上,Delphi的 register调用约定(也称为Borland fastcall)按顺序使用 EAX, EDX and ECX registers.

但是,Microsoft的fastcall调用约定使用不同的寄存器.它根本不使用EAX.相反,它使用ECX和EDX寄存器作为前两个参数,如described by the documentation.

因此,使用该信息,您可以通过将参数移动到EAX寄存器中来编写一些汇编程序来从C进行Delphi寄存器函数调用.但是,让Delphi编译器更容易实现这一点.特别是当我想象你的真正问题涉及多个功能而不仅仅是一个参数.

我建议您编写一些Pascal代码以适应stdcall和register.

function FuncRegister(param: Pointer): Integer; register; external '...'; function FuncStdcall(param: Pointer): Integer; stdcall; begin Result := FuncRegister(param); end; exports FuncStdcall;

然后你可以从你的C代码调用FuncStdcall,让Delphi编译器处理参数传递.

标签:寄存器

本文共计396个文字,预计阅读时间需要2分钟。

如何运用Delphi的Visual C寄存器调用约定实现函数调用的长尾?

我有一个用Visual C++ 2012编写的程序,我尝试调用用Delphi编写的函数(我没有源代码)。这是Visual C++中的代码:cppint _fastcall(test)(void*)=(int(_fastcall(*)(void*))0x00489A7D);test((void*)0x12345678);但在编译时遇到了问题。

我有一个用Visual C 2012编写的程序,我试图调用用Delphi编写的函数(我没有源代码).这是Visual C中的代码:

如何运用Delphi的Visual C寄存器调用约定实现函数调用的长尾?

int (_fastcall *test)(void*) = (int(_fastcall *)(void*))0x00489A7D; test((void *)0x12345678);

但在编译的代码中它实际上是:

.text:1000113B mov eax, 489A7Dh .text:10001140 mov ecx, 12345678h .text:10001145 call eax

我除外的是:

.text:1000113B mov ebx, 489A7Dh .text:10001140 mov eax, 12345678h .text:10001145 call ebx

我知道’fastcall’使用EAX,ECX,EDX作为参数,但我不知道为什么Visual C编译器使用EAX作为入口点. EAX不应该是第一个参数(12345678h)吗?

我试图在汇编代码中调用delphi函数并且它可以工作,但我真的想知道如何在不使用汇编的情况下执行此操作.

那么可以让Visual C编译器生成代码,就像我说的那样吗?如果是的话,怎么做?

在x86上,Delphi的 register调用约定(也称为Borland fastcall)按顺序使用 EAX, EDX and ECX registers.

但是,Microsoft的fastcall调用约定使用不同的寄存器.它根本不使用EAX.相反,它使用ECX和EDX寄存器作为前两个参数,如described by the documentation.

因此,使用该信息,您可以通过将参数移动到EAX寄存器中来编写一些汇编程序来从C进行Delphi寄存器函数调用.但是,让Delphi编译器更容易实现这一点.特别是当我想象你的真正问题涉及多个功能而不仅仅是一个参数.

我建议您编写一些Pascal代码以适应stdcall和register.

function FuncRegister(param: Pointer): Integer; register; external '...'; function FuncStdcall(param: Pointer): Integer; stdcall; begin Result := FuncRegister(param); end; exports FuncStdcall;

然后你可以从你的C代码调用FuncStdcall,让Delphi编译器处理参数传递.

标签:寄存器