2012-07-11 7 views
5

Ich lerne Assembler Programmierung auf FreeBSD. Ich benutze FreeBSD 9.0 i386 Release und Nasm Assembler.Warum gibt es immer ein nutzloses Funktionsargument im Stapel?

Als ich eine einfache syscall-Funktion schrieb, fand ich, dass ich einen nutzlosen Wert in den Stapel schieben musste, um den Code richtig laufen zu lassen.

Zum Beispiel:

; File:test.asm 
section .text 
    global _start 
_start: 
    xor eax,eax 
    ; Argument of exit() 
    push 0x0 
    ; Syscall of exit() 
    mov al,1 
    int 0x80 

habe ich den folgenden Befehl den obigen Code zu montieren und zu verknüpfen:

%nasm -f elf test.asm -o test.o 
%ld test.o -o test.bin 

Ich benutzte ktrace das Programm zu inspizieren und gefunden:

%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) 

So der Code nicht korrekt ausgeführt, weil ich 0 als das einzige Argument von exit() aber das Programm actua zur Verfügung gestellt ly rennen Sie Ausgang (1).

Dann habe ich meinen Code geändert.

; 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 

Dann wurde der Code korrekt ausgeführt.

Zuerst dachte ich, dass es wegen etwas wie "Stapelauffüllung" oder "Stapelausrichtung" wie Stack allocation, padding, and alignment war. Es könnte also die 16-Bit-Ausrichtung berücksichtigen. Aber ich habe es nicht gefunden. Zum Beispiel Dieser folgende Code:

; 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 

tatsächlich ausgeführt Ausfahrt (3). Es schien, dass es Bytes nicht ausgerichtet hat. Ich debuggen den obigen Code mit GDB, wenn die letzte Zeile im Begriff war, ausgeführt werden, war der Stapel etwas wie folgt aus:

0xFFFFFFFF -> esp 
0x00000003 
0x00000000 

Also hier meine Frage: Warum gibt es immer ein nutzloses Argument oder ist es eine Methode zur Arbeit um?

Antwort

7

Es ist ein Dummy-Argument, um die Leistung leicht zu erhöhen, indem ein Call/Ret-Befehlspaar verhindert wird.

$ 2.1 in dem unten stehenden Link Siehe:

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

+0

Dieser Link sehr nützlich ist. Vielen Dank! – Lion

+0

Sekunde, danke für die Referenz. –

+1

Ich lese das, aber ich verstehe nicht, wie die Verwendung eines zusätzlichen Arguments "call"/"ret" eliminiert. – sharptooth