Win32汇编 - 外部函数命名('@'的含义)

hak*_*010 0 assembly winapi nasm ld kernel32

正如我所见,extern汇编代码中的WinAPI函数具有类似的名称_ExitProcess@4.

@4部分的含义是什么,以及如何确定之后使用的数字@

我知道这与我们链接的DLL有关,但在很多情况下,不知道在使用后使用的是什么数字@,这会导致许多令人讨厌的undefined reference错误.

Ros*_*dge 6

正如Andreas H回答的那样,后面的@数字是函数在函数返回之前从堆栈中删除的字节数.这意味着应该很容易确定该数字,因为它是您需要在堆栈上推送以正确调用该函数的字节数.它应该是调用前PUSH指令的数量乘以4.在大多数情况下,这也是传递给函数的参数数量乘以4.

如果您想要仔细检查您是否获得了正确的号码并且安装了Microsoft Visual Studio,则可以从Developer Command Prompt中找到装饰符号名称,如下所示:

C:\> dumpbin /headers kernel32.lib | find "ExitProcess"
  Symbol name  : _ExitProcess@4
  Name         : ExitProcess
Run Code Online (Sandbox Code Playgroud)

如果您使用MinGW编译器工具链接汇编代码,则可以执行以下操作:

C:\> nm C:\MinGW\lib\libkernel32.a | find "ExitProcess"
00000000 I __imp__ExitProcess@4
00000000 T _ExitProcess@4
Run Code Online (Sandbox Code Playgroud)

您需要替换C:\MinGWMinGW安装的目录.

由于并非所有Windows API都驻留在kernel32导入库中,因此您需要kernel32使用Windows SDK文档中为要链接的API函数指定的导入库名称进行替换.例如,MessageBoxA您需要使用user32.libVisual Studio和libuser32.aMinGW.

请注意,很少有罕见的Windows API不使用stdcall调用约定.这些函数wsprintf就是采用可变数量的参数,stdcall调用约定不支持这些参数.这些函数_在它们的名称之前只有一个下划线,@之后没有或数字.它们还要求调用者从堆栈中删除参数.