我正在努力学习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