尽管使用gcc链接器,但未获得汇编代码的“ _printf”错误的未定义引用

时间:2018-11-10 09:46:59

标签: linux assembly x86 linker nasm

我正在尝试遵循Paul Carter撰写的PC Assembly一书中的练习。 http://pacman128.github.io/pcasm/

我试图在Ubuntu 18上从1.4第23页运行该程序。这些文件都可以在上面的github站点上找到。

由于原始代码是针对32位的,因此我使用

进行编译

nasm -f elf32

代表first.asm和asm_io.asm获取目标文件。我也编译driver.c

我使用gcc中的链接器并运行

gcc -m32 -o first first.o asm_io.o driver.o 

但是它不断给我带来很多错误,例如

对'_scanf'的未定义引用 未定义对'_printf'的引用

(注意_printf而不是printf出现是因为在文件asm_io.asm中进行了一些转换,以保持Windows和Linux OS的兼容性)

我不知道为什么会出现这些错误。我也尝试直接使用链接器运行

ld -m elf_i386 -e main -o first -first.o driver.o asm_io.o -I /lib/i386-linux-gnu/ld-linux.so.2 

和许多变体,因为它似乎没有与C库链接。

有帮助吗?坚持了一段时间,找不到类似问题的解决方案

1 个答案:

答案 0 :(得分:4)

当从C映射到ELF对象文件中的asm符号名称时,Linux不会在名称_之前添加 1

所以call printf而不是_printf,因为libc中没有_printf

无论“兼容性”代码执行了什么操作,这都是错的。仅Windows和OS X使用_printf,Linux使用printf

所以您配置错误或定义了错误的设置,或者需要更新/移植到Linux。


脚注1:在古代历史(例如20年前)中,具有a.out文件格式的Linux确实在符号名称上使用了下划线。


更新:该库使用NASM预处理器来%define _scanf scanf,依此类推,但是它要求您通过与ELF_TYPE 组装来手动定义nasm -d ELF_TYPE。 / p>

他们本可以自己because NASM pre-defines __OUTPUT_FORMAT__检测到ELF32或ELF64输出格式。有人应提交拉取请求,以使用以下类似的代码自动执行此检测:

%ifidn __OUTPUT_FORMAT__, elf32
  %define  ELF_TYPE 32
%elifidn __OUTPUT_FORMAT__, elf64
  %define  ELF_TYPE 64
%endif


%ifdef ELF_TYPE
...
%endif