我正在尝试遵循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库链接。
有帮助吗?坚持了一段时间,找不到类似问题的解决方案
答案 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