2012-07-11 19 views
5

Sto imparando la programmazione in linguaggio assembly su FreeBSD. Sto usando la versione i386 di FreeBSD 9.0 e l'assembler di Nasm.Perché c'è sempre un argomento di funzione inutile nello stack?

Quando ho scritto una semplice funzione syscall, ho scoperto che dovevo inserire un valore inutile nello stack per far funzionare correttamente il codice.

Ad esempio:

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

Ho usato il seguente comando per montare e collegare il codice sopra:

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

ho usato ktrace per ispezionare il programma e trovati:

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

Quindi il codice non è stato eseguito correttamente, perché ho fornito 0 come unico argomento di exit() ma il programma actua eseguire l'uscita (1).

Quindi ho cambiato il mio codice.

; 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 

Quindi il codice è stato eseguito correttamente.

All'inizio, pensavo che fosse a causa di qualcosa tipo "stack padding" o "stack alignment", come Stack allocation, padding, and alignment. Quindi potrebbe rispettare l'allineamento a 16 bit. Ma non l'ho trovato. Ad esempio, questo codice seguente:

; 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 

effettivamente eseguito uscita (3). Sembrava non allineare i byte. Metto a punto il codice di cui sopra con gdb, quando l'ultima riga stava per essere giustiziato, lo stack è stato qualcosa di simile:

0xFFFFFFFF -> esp 
0x00000003 
0x00000000 

Quindi, ecco la mia domanda: perché c'è sempre un argomento inutile o c'è un metodo per lavorare in giro?

risposta

7

È un argomento fittizio per aumentare leggermente le prestazioni impedendo una coppia di istruzioni call/ret.

Vedi $ 2.1 sul link qui sotto:

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

+0

Questo collegamento è molto utile. Grazie! – Lion

+0

in secondo luogo, grazie per il riferimento. –

+1

L'ho letto, ma non capisco come usare un argomento extra per eliminare 'call' /' ret'. – sharptooth

Problemi correlati