nasm-ld找不到printf

问题描述

我正在使用nasm 2.14.02在Ubuntu上。

我正在尝试通过将变量压入堆栈然后调用printf来使用nasm编写一个简单的hello world程序:

; Import c-lib printf
extern printf

; Define Message and Length
section .data:
  msg:      db "Hello People!",0xA
  msg_len   equ  $-msg

section .text:
  global _start

_start:
  push msg
  call printf

  mov eax,1
  mov ebx,0
  int 80h

使用nasm组装程序可以正常工作,但是当我尝试将其与ld链接时,会引发以下错误

ld: hello_world.o: in function `_start':
hello_world.asm:(.text:+0x6): undefined reference to `printf'

因此,似乎extern不会导入printf。我究竟做错了什么。从字面上看,这是我的第一个汇编程序,所以请使用简单的单词。

编辑:

我正在使用的命令是:

nasm hello_world.asm -f elf64
ld hello_world.o -o hello_world

解决方法

您需要将您的代码与提供 printf 的库相关联;这是由 C 标准库提供的。获得它的最简单方法是使用 gcc 为您调用链接器。

nasm -felf32 hello_world.asm
gcc -static -o hello_world hello_world.o

上面的将不起作用,但是,因为 gcc 将尝试添加一些在 crt1.o 中找到的额外代码,其中包含 _start 以启动 C 运行时,然后调用 { {1}}。

对您的代码进行最简单的修复是改为编写 main 方法。

main

我不是在 32 位机器上,所以我无法轻松测试,但我认为这正是您所需要的。使用 section .text: global main main: push ebp ; these two lines are the usual function entry mov ebp,esp push msg call printf xor eax,eax ; set eax to zero as the return value mov esp,ebp ; these two lines are the usual function exit pop ebp ret 然后使用 nasm,如上,组装和链接它。

如果您确实想使用 gcc,那很好。您需要链接 C 标准库(静态地......使用 GOT 是另一回事),可能使用 _start