我在NASM的程序集编程,我在代码中找到了这个:
extern _ExitProcess@4
;Rest of code...
@4
的含义是什么?
感谢。
答案 0 :(得分:4)
winapi使用__stdcall调用约定。调用者从右向左推送堆栈上的所有参数,被调用者再次弹出它们以清理堆栈,通常使用RET n
指令。
它是__cdecl调用约定的对象,是C和C ++代码中的常见默认值,调用者通常在CALL之后使用ADD ESP,n
指令清理堆栈。 __stdcall的优点是它可以生成更紧凑的代码,在被调用的函数中只有一个清理指令,而不是每次调用函数时都有很多。但是一个很大的缺点:它很危险。
潜在的危险潜伏在调用函数的代码中,该函数已使用函数的过时声明进行编译。例如,通过添加参数来更改函数时的典型情况。这结果非常糟糕,除了尝试使用不可用的参数的函数之外,新函数从堆栈中弹出太多参数。这会使堆栈失衡,不仅导致被调用者失败,还导致调用者失败。非常难以诊断。
所以他们做了一些事情,他们装饰函数的名称。首先使用前导_underscore,就像__cdecl函数一样。并且附加@n
,n
的值是函数末尾的RET
指令的操作数。或者换句话说,堆栈上参数占用的字节数。
这在不匹配时提供链接器诊断,foo(int)
函数更改为foo(int, int)
例如生成名称_foo@8
。尚未重新编译的调用代码将查找_foo@4
函数。链接器失败,无法找到该符号。避免灾难。
答案 1 :(得分:3)
答案 2 :(得分:3)
C的名称装饰方案记录在Format of a C Decorated Name。包含@
字符的修饰名称用于__stdcall
调用约定:
__stdcall
:前导下划线(_
)和尾随符号(@
)后跟一个表示参数列表中字节数的数字
像Dependency Walker这样的工具能够显示装饰和未装饰的名称。
非官方文档可在此处找到:Name Decoration