2012-07-11 5 views
5

Estoy aprendiendo programación de lenguaje ensamblador en FreeBSD. Estoy usando FreeBSD 9.0 i386 release y nasm assembler.¿Por qué siempre hay un argumento de función inútil en la pila?

Cuando escribí una función simple de syscall, descubrí que tenía que insertar un valor inútil en la pila para hacer que el código se ejecutara correctamente.

Por ejemplo:

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

I utilizó el siguiente comando para montar y enlazar el código anterior:

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

Solía ​​ktrace para inspeccionar el programa y conocer:

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

Así que el código no se ejecutó correctamente, porque proporcioné 0 como el único argumento de exit() pero el programa actua lly ejecute la salida (1).

Luego cambié mi código.

; 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 

Luego, el código se ejecutó correctamente.

Al principio, pensé que era por algo como "relleno de pila" o "alineación de pila", como Stack allocation, padding, and alignment. Por lo tanto, podría respetar la alineación de 16 bits. Pero no lo encontré. Por ejemplo, este código siguiente:

; 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 

realmente se ejecutó la salida (3). Parecía que no alineaba los bytes. Puedo depurar el código anterior con gdb, cuando la última línea estaba a punto de ser ejecutado, la pila fue algo como esto:

0xFFFFFFFF -> esp 
0x00000003 
0x00000000 

Así que aquí está mi pregunta: ¿por qué siempre hay un argumento inútil o hay un método para trabajar ¿alrededor?

Respuesta

7

Es un argumento ficticio para aumentar ligeramente el rendimiento al evitar un par de instrucción call/ret.

Ver $ 2,1 en el siguiente enlace:

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

+0

Este enlace es muy útil. ¡Gracias! – Lion

+0

en segundo lugar, gracias por la referencia. –

+1

Lo leí, pero no entiendo cómo el uso de un argumento adicional elimina 'call' /' ret'. – sharptooth

Cuestiones relacionadas