2012-07-11 35 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

相关问题