b0c*_*zz3 3 c++ windows assembly nasm visual-studio-2019
我在 Windows 10 中使用 Visual studio 2019,我想使用 MSVC(平台工具集 142)和 NASM(版本 2.14.02)在 x86 中编译以下代码:
foo.asm
section .text
global foo
foo:
mov eax, 123
ret
Run Code Online (Sandbox Code Playgroud)
主程序
extern "C" int foo(void);
int main()
{
int x = foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但我得到了错误:
在 x64 中运行良好,在 x86 中生成的文件 main.obj 向函数名 foo 添加前导下划线,从而生成 _foo。这在 x64 中不会发生,但将符号保留为 foo,而不是 _foo。
那么,是否有任何适用于 x86 和 x64 平台的解决方案(最好不修改源代码,也许是 MSVS 编译器的一些编译器/链接器标志)?
我真的很感谢任何帮助。
前缀_是名称修改的结果,这取决于目标平台 ABI(操作系统、位数、调用约定)。
根据 Microsoft 的说法,该_前缀用于 32 位 Windowscdecl调用约定,但不用于 64 位(来源):
\n\nC 修饰名称的格式
\nC 函数的修饰形式取决于其声明中使用的调用约定,如下表所示。这也是在 C++ 代码声明为具有 extern“C”链接时使用的装饰格式。默认调用约定是 __cdecl。请注意,在 64 位环境中,函数不会被修饰。
\n调用约定 \xe2\x80\x83\xe2\x80\x94\xe2\x80\x83 修饰
\n
\n__cdecl\xe2\x80\x83 前导下划线 (_)
\n__stdcall\xe2\x80\x83 前导下划线 (_) 和尾随 at 符号(@) 后跟参数列表中十进制字节数
\n__fastcall\xe2\x80\x83 前导和尾随符号 (@) 后跟表示参数列表中字节数的十进制数
\n__vectorcall\xe2\x80\ x83 参数列表中两个尾随符号 (@@) 后跟十进制字节数
背后的原因可能是 32/64 位 Windows 调用约定并不真正兼容。例如,64 位模式下的函数参数以不同的方式传递,并且必须在调用之间保留不同的寄存器。
\n无论如何,为了回答这个问题,我可以想出几个解决方案:
\n解决方案1
\n生成 的代码.asm应该仅在 32 位模式下添加前导_(生成的程序集可能也必须在其他方面有所不同,特别是在涉及指针的情况下)。
解决方案2
\n_使用预处理器在 64 位模式下添加前导:
#ifdef _WIN64\n# define foo _foo\n#endif\n\nextern "C" int foo(void);\n\nint main()\n{\n int x = foo();\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1431 次 |
| 最近记录: |