gpt4 book ai didi

macos - 如何解决我在尝试将 C++ 与 Assembly 链接时遇到的这个链接器错误?

转载 作者:行者123 更新时间:2023-12-05 00:57:45 26 4
gpt4 key购买 nike

我正在尝试链接 C++ 文件和程序集文件。汇编文件定义了一个名为 add 的 C++ 函数。 .我使用的是 64 位 Mac 操作系统。尝试编译程序时出现以下错误:

Undefined symbols for architecture x86_64:
"_add", referenced from:
_main in main-d71cab.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main.o] Error 1

生成文件
hello: main.o hello.o
g++ main.o hello.o -o hello

hello.o: hello.asm
nasm -f macho64 hello.asm -o hello.o

main.o: main.cpp
g++ main.cpp -o main.o

你好.asm
global add

segment .text
add:
mov rax, rdi
add rax, rsi
ret

主文件
#include <iostream>

extern "C" int add(int a, int b);

int main(int argc, char* argv[]) {

int a, b;

std::cout << "Enter two numbers\n";
std::cin >> a;
std::cin >> b;
std::cout << "Sum of a and b is " << add(a, b) << std::endl;

return 0;
}

我真的很感激任何帮助。谢谢!

最佳答案

在 OS/X 上,C 调用约定是,从对象导出时,函数必须有一个下划线(除非它被覆盖)才能对 C 可见。你是说 add 时使用 C 调用约定extern "C"在这个原型(prototype)上:

extern "C" int add(int a, int b);

这实际上是正确的,但是为了使您的汇编代码符合要求,您还需要确保您的汇编函数将是全局的并且对 C/C++ 代码可见,它们的前导下划线。您的汇编代码将像这样开始:
global _add

segment .text
_add:

您遇到的另一个问题是您的 Makefile以及生成 main.o 的方式来自 main.cpp .
main.o: main.cpp
g++ main.cpp -o main.o

这告诉 g++编译 main.cpp可执行调用 main.o .你真正想做的是告诉 g++跳过到可执行部分的链接,以及输出文件 main.o实际上是 对象 .为此,将行更改为:
main.o: main.cpp
g++ -c main.cpp -o main.o
-c选项表示跳过链接阶段(生成可执行文件并简单地输出稍后将链接的对象)。

当它尝试制作 main.o 时,如果没有此更改,它认为你想要一个可执行文件,并且找不到函数 _add因为它不在它知道的文件中。它在 hello.o但命令 g++ main.cpp -o main.o不知道。

关于macos - 如何解决我在尝试将 C++ 与 Assembly 链接时遇到的这个链接器错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34192828/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com