私は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で上記のコードをデバッグ周り?
このリンクは非常に便利です。ありがとう! – Lion
秒、参考に感謝します。 –
私はそれを読んでいますが、余分な引数を使って 'call' /' ret'を取り除く方法は分かりません。 – sharptooth