6

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

だからここに私の質問があります.なぜいつも役に立たない議論があるのか​​ 、それとも回避する方法があるのですか?

4

1 に答える 1

7

call/ret 命令ペアを回避することでパフォーマンスをわずかに向上させるための仮引数です。

以下のリンクで $2.1 を参照してください。

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

于 2012-07-11T13:32:49.527 に答える