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

Iは、上記のコードをアセンブルし、リンクするために、以下のコマンドを使用:

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

Iプログラムを検査するた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) 

コードが正しく実行されなかったので、exit()の唯一の引数として0を指定しましたが、プログラムのアクチュアlly exit(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 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 

実際に実行されたexit(3)。バイトを整列していないように見えました。

0xFFFFFFFF -> esp 
0x00000003 
0x00000000 

だからここに私の質問です:なぜ仕事に方法は役に立たないの引数は、常にありますかあり、最後の行が実行されようとしていたとき、私は、スタックはこのような何かをした、gdbで上記のコードをデバッグ周り?

答えて

7

コール/リターン命令のペアを防ぐことによって、パフォーマンスをわずかに向上させることは、仮引数です。

は、以下のリンクで$ 2.1参照:

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

+0

このリンクは非常に便利です。ありがとう! – Lion

+0

秒、参考に感謝します。 –

+1

私はそれを読んでいますが、余分な引数を使って 'call' /' ret'を取り除く方法は分かりません。 – sharptooth

関連する問題