简体   繁体   English

NASM 中 printf 最简单的工作示例失败

[英]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.old -o worked-example worked-example.o -lc都阻止了错误消息 - 但随后文件工作示例 - 无法找到./worked -example -即使它可以用catls看到

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM