Linux 在64位ubuntu上编译32位汇编程序
我的程序是用32位汇编语言写的。。。现在我无法在64位操作系统上编译它。在我们学校,它们是特定的,程序必须以32位版本编写。这是我的节目:Linux 在64位ubuntu上编译32位汇编程序,linux,ubuntu,assembly,64-bit,32-bit,Linux,Ubuntu,Assembly,64 Bit,32 Bit,我的程序是用32位汇编语言写的。。。现在我无法在64位操作系统上编译它。在我们学校,它们是特定的,程序必须以32位版本编写。这是我的节目: bits 32 extern _printf global _start section .data message db "Hello world!!", 10, 0 section .text _start: pushad push dword message call _printf add esp,
bits 32
extern _printf
global _start
section .data
message db "Hello world!!", 10, 0
section .text
_start:
pushad
push dword message
call _printf
add esp, 4
popad
ret
有什么想法吗?我已经尝试了很多方法来编译它。
编译后的错误输出:
nasm -f elf64 vaja4.asm
ld vaja4.o -o vaja4
./vaja4
输出:
vaja4.o: In function `_start':
vaja4.asm:(.text+0x7): undefined reference to `_printf'
在我看来,您似乎忘记了链接C库,该库提供了
printf
函数(以及其他函数):
我怀疑您看到的错误是因为32/64位问题。您看到的错误,即
vaja4.asm:(.text+0x7): undefined reference to `_printf'
清楚地告诉您符号u printf未定义,这意味着printf函数库未被链接
你的链接步骤,即
ld vaja4.o -o vaja4
不包括任何库。您需要将程序链接到一个可以提供printf函数定义的库。我相信ld应该自己选择库,而不会因为这些消息而打扰您,但因为它无法找到适合此函数的C库,我猜您没有所需的库,即32位或64位库缺失
无论如何,请尝试以下命令序列来组装和链接程序:
nasm -f elf vaja4.asm
ld -m elf_i386 vaja4.o vaja4
./vaja4
首先将
\u printf
更改为printf
,将\u start
符号更改为main
,然后使用gcc
链接对象文件,该文件将自动链接到libc
,您需要这样做,因为如果没有main
,您就无法链接到libc。此外,组装时应使用elf32而不是elf64,因为代码有32位指令:
bits 32
extern printf
global main
section .data
message db "Hello world!!", 10, 0
section .text
main:
pushad
push dword message
call printf
add esp, 4
popad
ret
并通过以下方式构建:
nasm -f elf32 vaja4.asm
gcc -m32 vaja4.o -o vaja4
$./test
$Hello world!!
编辑:
由于您现在正在64位系统上编译32位代码,因此需要安装32位版本的库
apt-get install ia32-libs
在Ubuntu 12.10上,首先需要安装开发包
sudo apt-get update
sudo apt-get install libc6-dev-i386
为了
工作。这不应该是printf吗?相同的错误:vaja4.o:In function
start”:vaja4.asm:(.text+0x7):未定义对
printf的引用是的,这是正确的方法。如果您想使用libc,您应该使用main
作为入口点,并使用gcc进行链接,以便引入适当的libc片段,并处理初始化/关闭。另外,只需从main
返回works,如果您创建的二进制文件没有libc,则必须使用退出系统调用。在gcc-m32 vaja4.o-o vaja4之后,它给了我一个错误输出:您需要安装32位库apt get install ia32 libsI试图安装该库,但仍然是相同的错误。现在我安装了libc6-dev-i386库,它可以正常工作了!Ty:)您可以从只定义\u start
的程序链接libc。但是,如果要生成静态二进制文件,则必须调用glibc的init函数,或者使用不需要init函数的libc(如musl)。(Linux上的动态链接在\u start
之前调用glibc的init函数)。请看我对这个问题的回答,我把这个问题标为重复的。(\u printf
与printf
的问题是分开的,但除此之外它要求的是相同的事情)或者甚至ld-m elf\u i386-I/lib/ld linux.so.2-lc vaja4.o-o vaja4
可能不需要输出文件名上的-I
开关-肯定需要-lc
和-o
。\u start
标签跳转到,而不是调用。因此,您无法从它中ret
。更易于使用main
和gcc。。。
sudo apt-get update
sudo apt-get install libc6-dev-i386
gcc -m32 vaja4.o -o vaja4