Win32 Assembly-Extern函数命名("@"的含义) [英] Win32 Assembly - Extern function naming (The meaning of '@')

查看:132
本文介绍了Win32 Assembly-Extern函数命名("@"的含义)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As I see, extern WinAPI functions in assembly code have names like _ExitProcess@4.

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

What is the meaning of the @4 part, and how to determine what number to use after @ ?

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

I know that this has something to do with DLL we are linking against, but in many cases it's not known what number to use after the @, and this leads to many nasty undefined reference errors.

推荐答案

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

As Andreas H answer said the number after the @ is the number of bytes the function removes from stack before the function returns. This means it should be easy to determine that number, as it's the also number of bytes you need push on the stack to correctly call the function. It should be the number of PUSH instructions before the call multiplied by 4. In most cases this will also be the number of arguments passed to the function multiplied by 4.

如果您要仔细检查是否已获得正确的编号并且已安装Microsoft Visual Studio,则可以从开发人员命令提示符中找到修饰后的符号名称,如下所示:

If you want to double check that you've gotten the right number and you have Microsoft Visual Studio installed you can find the decorated symbol name from the Developer Command Prompt like this:

C:\> dumpbin /headers kernel32.lib | find "ExitProcess"
  Symbol name  : _ExitProcess@4
  Name         : ExitProcess

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

If you're using the MinGW compiler tools to link your assembly code, you can do this instead:

C:\> nm C:\MinGW\lib\libkernel32.a | find "ExitProcess"
00000000 I __imp__ExitProcess@4
00000000 T _ExitProcess@4

您需要将C:\MinGW替换为您安装的MinGW的目录.

You'll need to replace C:\MinGW with the directory you installed MinGW.

由于并非所有Windows API都驻留在kernel32导入库中,因此您需要用Windows SDK文档中要链接的API函数给定的导入库名称替换kernel32.例如,对于MessageBoxA,您需要在Visual Studio中使用user32.lib,而在MinGW中使用libuser32.a.

Since not all Windows APIs reside in the kernel32 import library you'll need to replace kernel32 with the name of the import library given in the Windows SDK documentation for the API function you want to link to. For example, with MessageBoxA you'd need to use user32.lib with Visual Studio and libuser32.a with MinGW instead.

请注意,很少有不使用stdcall调用约定的Windows API.这些是像wsprintf这样的函数,它们带有可变数量的参数,而stdcall调用约定不支持这些参数.这些函数的名称前仅带有下划线_,其后没有@或数字.它们还要求调用者从堆栈中删除参数.

Note there are few rare Windows APIs that don't use the stdcall calling convention. These are functions like wsprintf that take a variable number of arguments, which the stdcall calling convention doesn't support. These functions just have an underscore _ before their names, and no @ or number after. They also require that the caller remove the arguments from the stack.

这篇关于Win32 Assembly-Extern函数命名("@"的含义)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆