ubuntu x86-64位機器下編譯32位彙編的問題

不是大牛的小劉發表於2019-03-16

示例程式碼:

# movtest3.s

.section .data
output:
	.asciz "The value is %d\n"
values:
	.int 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60

.section .text
.globl _start
_start:
	nop
	movl $0, %edi
loop:
	movl values(, %edi, 4), %eax
	pushl %eax
	pushl $output
	call printf
	addl $8, %esp
	inc %edi
	cmpl $11, %edi
	jne loop
	movl $0, %ebx
	movl $1, %eax
	int $0x80

彙編:as --32 movtest3.s -o movtest3.o

連結:ld -o movtest3 movtest3.o -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -L/lib/i386-linux-gnu -lc

當中可能會碰到的幾個問題:

如果提示"invalid instruction suffix for `push'",是因為彙編時沒有用--32來指定按32位來編譯;

如果不加-m elf_i386指定基於32位平臺連結,會報錯:ld: i386 架構於輸入檔案 movtest3.o 與 i386:x86-64 輸出不相容;

如果提示"對‘printf’未定義的引用",是因為連結時沒有指定C庫;

如果提示"ld: 找不到 -lc",則可能是C庫路徑不對或軟連結問題,先通過locate libc.so查詢本機c庫的路徑,比如我的電腦查詢結果如下:

/lib/i386-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libc.so.6
/usr/lib/x86_64-linux-gnu/libc.so

一般通過路徑名就能區分32位和64位,如果想進一步確認,可以通過file命令檢視.

$ file /lib/i386-linux-gnu/libc.so.6
/lib/i386-linux-gnu/libc.so.6: symbolic link to libc-2.23.so // libc.so.6是一個軟連結
$ file /lib/i386-linux-gnu/libc-2.23.so 
/lib/i386-linux-gnu/libc-2.23.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=dd5192a769e33ed6ca68a6ab5740ff9e8ec678a7, for GNU/Linux 2.6.32, stripped

我的電腦沒有libc.so這個軟連結,在/lib/i386-linux-gnu/目錄下,執行sudo ln -sf libc.so.6 libc.so,再次連結,通過.

相關文章