[英]Simplest worked example of printf in NASM fails
Using this code:使用此代码:
section .data
msg db "Most basic printf example in NASM", 0xA, 0xD, 0
len equ $-msg
section .bss
section .text
global _start
extern printf
_start:
mov rsi, msg
push rax ;; for stack alignment
call printf
fails with the error undefined reference to `printf'失败并出现错误undefined reference to `printf'
I'm trying to create the simplest worked example of calling printf
from NASM.我正在尝试创建从 NASM 调用printf
的最简单的工作示例。
I had read suggestions of adding -lc
to ld ie:我已经阅读了将-lc
添加到 ld 的建议,即:
ld -o worked-example -lc worked-example.o
or ld -o worked-example worked-example.o -lc
both prevent the error message - but then the file worked-example - can't be found with./worked-example - even though it can be seen with cat
and ls
ld -o worked-example -lc worked-example.o
或ld -o worked-example worked-example.o -lc
都阻止了错误消息 - 但随后文件工作示例 - 无法找到./worked -example -即使它可以用cat
和ls
看到
file worked-example
indicates: worked-example: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld64.so.1, with debug_info, not stripped file worked-example
指示:工作示例:ELF 64 位 LSB 可执行文件,x86-64,版本 1 (SYSV),动态链接,解释器 /lib/ld64.so.1,带 debug_info,未剥离
EDIT: Based on comments below, I found the dynamic linker and tried to add that: ld worked-example.o -o worked-example -lc -dynamic-linker /usr/lib64/ld-linux-x86-64.so.2
which works.编辑:根据下面的评论,我找到了动态 linker 并尝试添加: ld worked-example.o -o worked-example -lc -dynamic-linker /usr/lib64/ld-linux-x86-64.so.2
哪个有效。 [With a segfault and nothing printed - but it compiles and runs] [带有段错误并且没有打印 - 但它可以编译并运行]
Michael helped fill in the missing pieces.迈克尔帮助填补了缺失的部分。 The biggest issue is the linker command.最大的问题是 linker 命令。 Compile with:编译:
nasm -f elf64 -F dwarf -g worked-example.asm
Then the linker needs to a call to the dynamic linker :然后 linker 需要调用动态 linker :
ld worked-example.o -o worked-example -lc -dynamic-linker /usr/lib64/ld-linux-x86-64.so.2
The exact path will vary by distro.确切的路径将因发行版而异。
Use `sudo find / -iname ld-linux-x86-64.so.2" to find the correct path for your system.使用 `sudo find / -iname ld-linux-x86-64.so.2" 为您的系统找到正确的路径。
In focusing on the linking problems, I forgot to end the program cleanly:在关注链接问题时,我忘了干净地结束程序:
mov eax, 1 ; sys exit
mov ebx, 0 ; all OK
int 80h ; call the kernel
Perhaps, the easiest to understand worked example is:也许,最容易理解的工作示例是:
section .data
msg db "Most basic printf example in NASM", 0xA, 0
len equ $-msg
section .bss
section .text
global _start
extern printf
_start:
mov rdi, msg
call printf
;end gracefully
mov eax, 1
mov ebx, 0
int 80h
However, there are a few problems with that.但是,这样做存在一些问题。 In deference to Peter, this is a more refined, basically identical, approach:尊重彼得,这是一种更精致、基本相同的方法:
section .data
msg: db "Most basic printf example in NASM", 0xA, 0
len equ $-msg
section .text
global _start
extern printf
extern exit
_start:
xor eax, eax ; 0 FP args
lea rdi, [rel msg]
call printf
xor edi, edi
call exit ; exit(0)
; let C handle any stdio flushing before exiting
; see here: https://stackoverflow.com/questions/38379553/using-printf-in-assembly-leads-to-an-empty-ouput
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.