1. 程式人生 > >64位ubuntu下編譯32位彙編程式(同時連結C庫)

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)