我正在學習FreeBSD上的彙編語言編程。我正在使用FreeBSD 9.0 i386發行版和nasm彙編程序。爲什麼堆棧中總會有無用的函數參數?
當我編寫了一個簡單的系統調用函數時,我發現我必須將一個無用的值推入堆棧以使代碼正確運行。
例如:
; File:test.asm
section .text
global _start
_start:
xor eax,eax
; Argument of exit()
push 0x0
; Syscall of exit()
mov al,1
int 0x80
我用下面的命令彙編和鏈接上面的代碼:
%nasm -f elf test.asm -o test.o
%ld test.o -o test.bin
我以前的ktrace以檢查程序,並發現:
%ktrace ./test.bin
%kdump -d -f ./ktrace.out
2059 ktrace RET ktrace 0
2059 ktrace CALL execve(-1077940941,-1077941260,-1077941252)
2059 ktrace NAMI "./test.bin"
2059 test.bin RET execve 0
2059 test.bin CALL exit(1)
所以代碼沒有正確運行,因爲我提供了0作爲exit()的唯一參數,但程序實體lly跑出口(1)。
然後我改變了我的代碼。
; File:test.asm
section .text
global _start
_start:
xor eax,eax
push 0x0
; Whatever digits,0x1,0x2...0xFFFFFFFF, ect.
push 0xFFFFFFFF
mov al,1
int 0x80
然後代碼被正確執行。
起初,我雖然是因爲像「stack padding」或「stack alignment」這樣的東西,比如Stack allocation, padding, and alignment。所以它可能尊重16位對齊。但我沒有發現。例如,以下代碼:
; File:test.asm
section .text
global _start
_start:
xor eax,eax
push 0x0
; Actual argument of exit()
push 0x3
push 0xFFFFFFFF
; Syscall of exit()
mov al,1
int 0x80
實際執行的出口(3)。它似乎沒有對齊字節。我調試用gdb上面的代碼,當最後一行即將被執行,堆棧是這樣的:
0xFFFFFFFF -> esp
0x00000003
0x00000000
因此,這裏是我的問題:爲什麼總有一個無用的說法還是有工作的方法周圍?
這個環節是非常有用的。謝謝! – Lion 2012-07-11 13:42:02
秒,感謝您的參考。 – 2012-07-11 20:06:44
我讀到了,但我不明白如何使用額外的參數消除'call' /'ret'。 – sharptooth 2012-07-12 12:08:10