FreeBSD でアセンブリ言語プログラミングを学んでいます。FreeBSD 9.0 i386 リリースと nasm アセンブラーを使用しています。
単純な syscall 関数を作成したとき、コードを正しく実行するには、役に立たない値をスタックにプッシュする必要があることがわかりました。
例えば:
; 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)
そのため、exit() の唯一の引数として 0 を指定したため、コードは正しく実行されませんでしたが、プログラムは実際には 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
その後、コードは正しく実行されました。
最初は、「スタック パディング」や「スタックアラインメント」のようなものが原因だと思っていました。したがって、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) を実行しました。バイトが整列していないようでした。上記のコードを gdb でデバッグすると、最後の行が実行されようとしていたときに、スタックは次のようになりました。
0xFFFFFFFF -> esp
0x00000003
0x00000000
だからここに私の質問があります.なぜいつも役に立たない議論があるのか 、それとも回避する方法があるのですか?