我正在Windows 10中使用Visual Studio 2019,并且我想使用下一个代码的MSVC(平台工具集142)和NASM(版本2.14.02)在x86中进行编译:
foo.asm
section .text
global foo
foo:
mov eax, 123
ret
main.cpp extern "C" int foo(void);
int main()
{
int x = foo();
return 0;
}
但是我得到了错误:在x64中运行良好,在x86中,生成的文件main.obj在函数名称foo前面添加了下划线,结果为_foo。在x64中不会发生这种情况,但是会将符号保留为foo,而不是_foo。
那么,是否有任何解决方案既可用于x86平台,又可用于x64平台(最好不修改源代码,或者为MSVS编译器提供一些编译器/链接器标志)?
我非常感谢您的帮助。
最佳答案
_
前缀是名称处理的结果,该名称处理取决于目标平台ABI(操作系统,位,调用约定)。
根据Microsoft的说法,_
前缀用于32位Windows cdecl
调用约定中,而不用于64位(source):
背后的原因可能是32/64位Windows调用约定并非真正兼容。例如,64位模式下的函数参数以不同的方式传递,并且在两次调用之间必须保留不同的寄存器。
无论如何,要回答这个问题,我可以想到几个解决方法:
解决方案1
生成.asm
的代码应仅在32位模式下添加前导_
(生成的程序集可能也必须在其他方面有所不同,尤其是在涉及指针的情况下)。
解决方案2
使用预处理器以64位模式添加前导_
:
#ifdef _WIN64
# define foo _foo
#endif
extern "C" int foo(void);
int main()
{
int x = foo();
return 0;
}
关于c++ - x86中的下划线前缀问题:从C++函数调用NASM函数在x64中有效,但在x86中失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62753691/