我一直在寻找如何解决这个问题的几个小时。通过键入
运行它nasm -f elf64 hello.asm
ld -s -o hello hello.o
并获得以下内容:
ld: warning: cannot find entry symbol _start; defaulting to 00000000004000b0
hello.o: In function `main':
hello.asm:(.text+0x12): undefined reference to `printf'
如果我gcc hello.o
,那么./a.out
就可以了,但随后存储库中会有一个额外的.a
文件。
对此非常陌生,在压缩的夏季课程中,教授正在让我们学习Linux和github来完成我们的任务!关于我做错什么的任何想法?
;hello.asm
bits 64
global main
extern printf
section .text
main:
; function setup
push rbp
mov rbp, rsp
sub rsp, 32
;
lea rdi, [rel message]
mov al, 0
call printf
; function return
mov eax, 0
add rsp, 32
pop rbp
ret
section .data
message: db 'Course: COSC2425 Lab2',0x0D,0x0a,'Student: firstname lastname',0x0D,0x0a,'Project: Nasm Hello World'
答案 0 :(得分:0)
Haven没有使用nasm,但是使用气体程序如下。创建对象:
as -o hello.o hello.s
现在,因为你正在调用printf链接是针对ld-linux.so.2,根据Richard Bloom或调整为64位架构
ld --dynamic-linker /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 -o hello -lc hello.o
仔细检查ld-linux-x86-64.so.2的正确位置在你的Linux中可能在其他地方。顺便说一句,你的代码在退出时是segfaulting。只有这样才能让它正常退出:
global _start
extern printf
section .text
_start:
mov rdi, format
mov rsi, message
mov rax, 0
call printf
mov rax, 1
mov rbx, 0
int 80h
section .data
message: db 'Course: COSC2425 Lab2',0x0a,'Student: firstname lastname',0x0a,'Project: Nasm Hello World',0x0a,0
format: db '%s', 0
main
重命名为_start
以消除链接器警告。
答案 1 :(得分:0)
printf
是标准C库的一部分。使用gcc
编译程序会在链接时自动添加此库。如果您手动使用ld
,则需要将库与程序链接。试试这个:
ld -I/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 -lc -s -o hello hello.o
此外,默认情况下,ld
将查找名为_start
的全局标签,这是程序执行开始的地方。您需要将global main
更改为global _start
,将main:
更改为_start:
,或者您需要通过以下方式告知ld
您的计划开始位置:
ld -I/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 -lc -e main -s -o hello hello.o