2012-07-11 33 views
5

我正在學習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 

因此,這裏是我的問題:爲什麼總有一個無用的說法還是有工作的方法周圍?

回答

7

這是一個虛擬參數,通過阻止調用/ ret指令對來提高性能。

見$ 2.1以下鏈接:

http://www.int80h.org/bsdasm/#default-calling-convention

+0

這個環節是非常有用的。謝謝! – Lion 2012-07-11 13:42:02

+0

秒,感謝您的參考。 – 2012-07-11 20:06:44

+1

我讀到了,但我不明白如何使用額外的參數消除'call' /'ret'。 – sharptooth 2012-07-12 12:08:10

相關問題