【发布时间】:2020-07-27 08:42:41
【问题描述】:
我在 .asm 文件中有一些 x86 代码,我正在尝试从 C++ 中使用它:
C++
#include <iostream>
extern "C" int addInts(int a, int b);
int main() {
int a = 1;
int b = 2;
int result = addInts(a, b);
std::cout << "Result :\t" << result << std::endl;
return 0;
}
组合
.386
.MODEL FLAT, C
.CODE
addInts PROC
PUSH EBP
MOV EBP, ESP
MOV EAX, [EBP+8]
MOV ECX, [EBP+12]
ADD EAX, ECX
POP EBP
RET
addInts ENDP
END
尝试运行此结果:
LNK4042(警告)多次指定对象,忽略额外内容(asm 对象文件)
LNK2019(错误)无法解析的外部符号 _addInts 在函数 _main(asm 目标文件)中引用
由于未解决的外部(解决方案可执行文件),最后的反抗行为采取致命错误 LNK1120 的形式
我正在使用带有 MSVC v142 和 MASM 的 Visual Studio 2019。我的其他自包含汇编代码没有问题,我编写的另一个函数涉及从 C++ 读取 x86 中的 int 数组工作正常。我真的看不出这里出了什么问题,如果是我的代码有问题,一些深奥的设置,或者完全是其他什么。
如果我将 Asm 代码的最后一行更改为 END addInts,那么程序将运行并立即退出,std::cout 中没有任何内容。
解决方案文件没有在链接器设置中定义入口点,这是我为最后一段从 C++ 调用 asm 的代码所做的。
asm 文件包含在构建中,使用 Microsoft Macro Assembler。
cpp 文件设置为编译为 C++,以防万一。
【问题讨论】:
-
你如何调用你的编译器和链接器(或配置你的IDE来这样做)?这是您的问题中缺少的信息,但对于调查您的问题是必需的。
-
我正在使用 Visual Studio 调试器 (F5) 运行它。我没想过要包含它,这是我运行所有其他代码的方式,并且没有出现问题。我希望这能回答你的问题,我还没有真正处理过这种事情,可能还不够准确。至于构建设置等,它都是为 x86 设置的,带有 /MACHINE:X86 标志
-
附加:如果我尝试在没有调试器 (Ctrl-F5) 的情况下运行它,我会得到相同的错误
-
显示 ML.EXE 的命令行(可以在 .asm 文件属性中看到)。你是按照this guide添加的文件吗?
-
ml.exe /c /nologo /Zi /Fo"Debug\IntegerAddition.obj" /Fl"" /W3 /errorReport:prompt /Ta,它是默认的,与以前工作的其他 asm 文件相同。我将它添加到项目中的方式与链接中描述的几乎相同,除了使用 Win32 而不是 x64