64位ubuntu下編譯32位彙編程式(同時連結C庫)
cmd.s如下:
//.include "linux.s"
.section .data
output1:
.ascii "There are %d parameters:\n\0"
//output2:
// .ascii "%s/0"
.section .text
.globl _start
_start:
movl (%esp), %ecx
pushl %ecx
pushl $output1
call printf
addl $4, %esp
popl %ecx
movl %esp, %ebp
pushl $0
call exit
as --32 cmd.s -o cmd.o
ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 cmd.o -o cmd -lc
--32宣告為32位程式
連結時elf_i386也是表明連結32位庫
-dynamic-linker /lib/ld-linux.so.2 使我們能連結到庫,這樣可執行檔案會在執行前生成,而作業系統將載入程式/lib/ld-linux.so.2,以載入外部庫並將其連結到程式。這種程式稱為動態連結器。
選項-lc表示:連結庫c。該庫在GNU/Linux系統上的檔名稱為libc.so。給定庫名,在本例中為c(通常庫不止一個字元),GNU/Linux連結器就愛那個字串lib加至庫名前,就愛那個字串.so加到庫名後,構成庫檔名。這個庫包含很多函式以自動執行各種任務。我們使用了printf和exit。
當我們使用-lc來連結cmd程式時,將該選項告訴連結器使用c庫(即libc.so)來尋找未在cmd,o中定義過的符號。但實際上這並未增加任何程式碼到我們的程式,只是在程式中說明到哪裡尋找。程式cmd開始時,首先載入檔案/lib/ld-linux.so.2,這是動態連結器,會檢視cmd程式,並法線改程式需要c庫才能執行。因此連結器在標準目錄(即/etc/ld.so.conf下以及環境變數LD_LIBRARY_PATH中的所有目錄下)查詢名為libc.so的庫,然後在庫中查詢所需符號(即printf和exit),並載入到程式的虛擬記憶體。最後,連結庫以庫中printf的實際位置代替程式中的printf的所有例項。
執行ldd ./cmd
這次會報如下資訊
linux-gate.so.1 => (0xf7763000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7590000)
/lib/ld-linux.so.2 (0xf7764000)