1

mips abi によると、呼び出し元はパフォーマンスのために最初のいくつかの引数を GPR に入れ、これらの引数をスタック フレームにプッシュしません。しかし、varargs api(stdarg.h) を使用して、void func(int type, ...); などの可変引数リストを持つ関数を定義すると、API が機能します。

stdarg.h API はスタック内の引数のみを検索することがわかりました。コンパイラが最初のいくつかの引数のみを GPR にプッシュする場合、stdarg.h はなぜ機能しますか? ABIについて何か見逃しましたか?

4

1 に答える 1

2

可変個引数関数の規則については、MIPS ELF ABIのページ 3-46 で説明されています。基本的に、呼び出された関数が可変長 (宣言された引数リストが ' ...' で終わる) の場合、コンパイラは最初の引数 (レジスタに渡された) をスタックに書き込むコードを追加します。$4スタック フレームには、最初の 4 つの引数 (正確には、レジスタでに渡される 4 ワード) 用のスペースが常に含まれています$7。したがって、呼び出し元は、関数が可変長引数であったかどうかを認識する必要はありません (浮動小数点引数の可能性を除いて; とにかく、呼び出し元と呼び出し先の両方が同じプロトタイプを見て使用するのが最善です)。

C 可変個引数関数をコンパイルし、生成されたアセンブリを見ると、関数の先頭付近に次のような行が表示されます。

sw      $5,52($sp)
sw      $6,56($sp)
sw      $7,60($sp)

その引数からスタックへのプロセスに対応します。

于 2011-03-14T14:49:13.763 に答える