Winapi 函数声明处的NASM@symbol

Winapi 函数声明处的NASM@symbol,winapi,assembly,nasm,Winapi,Assembly,Nasm,我在NASM的汇编程序中编程,我在代码中发现了以下内容: extern _ExitProcess@4 ;Rest of code... @4是什么意思? 谢谢。这是一个名称装饰,指定函数参数的总大小: 在参数列表中,名称后跟at符号@,后跟十进制字节数 C的名称装饰方案记录在。包含@字符的修饰名称用于u stdcall调用约定: __stdcall:前导下划线和尾随符号@,后跟表示参数列表中字节数的数字 像这样的工具能够显示修饰过的和未修饰过的名称 可以在此处找到非官方文档:winapi使用u

我在NASM的汇编程序中编程,我在代码中发现了以下内容:

extern _ExitProcess@4
;Rest of code...
@4是什么意思?
谢谢。

这是一个名称装饰,指定函数参数的总大小:

在参数列表中,名称后跟at符号@,后跟十进制字节数


C的名称装饰方案记录在。包含@字符的修饰名称用于u stdcall调用约定:

__stdcall:前导下划线和尾随符号@,后跟表示参数列表中字节数的数字

像这样的工具能够显示修饰过的和未修饰过的名称


可以在此处找到非官方文档:

winapi使用u stdcall调用约定。调用者从右向左推送堆栈上的所有参数,被调用者再次弹出这些参数以清理堆栈,通常使用RET n指令

这是一个A/*CDECL调用约定的反序号,C和C++代码中的常见缺省值,其中调用方清理堆栈,通常在调用之后加上ESP,N指令。_uustdcall的优点是它可以生成更紧凑的代码,在被调用的函数中只生成一条清理指令,而不是每次调用函数都生成多条清理指令。但有一个很大的缺点:它是危险的

危险潜伏在调用函数的代码中,该函数是用过期的函数声明编译的。例如,通过添加参数更改函数时的典型情况。结果非常糟糕,除了函数尝试使用不可用的参数外,新函数会从堆栈中弹出太多参数。这会使堆栈失衡,不仅会导致被调用方失败,还会导致调用方失败。极难诊断

所以他们做了一些事情,他们装饰了函数的名称。首先使用前导的_下划线,就像对u cdecl函数所做的那样。并附加@n,n的值是函数末尾RET指令的操作数。或者换句话说,堆栈上的参数占用的字节数


这将在出现不匹配时提供链接器诊断,例如,将fooint函数更改为fooint,int将生成名称_foo@8. 尚未重新编译的调用代码将查找_foo@4作用链接器失败,无法找到该符号。避免了灾难。

谢谢。有没有办法确定有多少字节?如果是Windows API函数,您可以查看函数原型。然后把参数的大小加起来。例如,接受六个参数,每个参数的大小为4字节,这需要了解所使用的类型。所以这个符号应该是_CreateThread@24Thank你,非常有帮助。+1对比cdecl和stdcall来推断名字装饰的必要性。这是一个很好的解释,它超越了“是什么”和“为什么”。