尽管使用 gcc 链接器"_printf"但获取对汇编代码错误的未定义引用



我正在努力学习Paul Carter的《PC组装》一书中的练习。http://pacman128.github.io/pcasm/

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

由于原始代码是32位的,我使用进行编译

nasm-f elf32

用于first.asm和asm_io.asm以获取对象文件。我还编译了驱动程序.c

我使用gcc的链接器并运行

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

但它总是给我一堆错误,比如

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

(注意_printf而不是printf,因为在文件asm_io.asm中进行了一些转换,以保持windows和linux操作系统之间的兼容性(

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

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库链接。

有什么帮助吗?陷入困境一段时间,无法找到类似问题的解决方案

Linux在ELF对象文件中从C映射到asm符号名称时,不会将_前置到名称1

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

无论"兼容性"代码做了什么,都是错误的。只有Windows和OS X使用_printf,Linux使用printf

因此,要么您配置错误,要么定义了错误的设置,要么它需要更新/移植到Linux。


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


更新:库对%define _scanf scanf等使用NASM预处理器,但需要通过与nasm -d ELF_TYPE组装手动定义ELF_TYPE

他们可能自己检测到ELF32或ELF64输出格式,因为NASM预先定义了__OUTPUT_FORMAT__。有人应该提交一个拉取请求,让这种检测自动进行,代码如下:

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

%ifdef ELF_TYPE
...
%endif

最新更新