2

スタックフレーム内にアセンブリx86コードに新しい関数と命令を挿入する場合、スタックサイズを増やす必要がありますか?はいの場合、いくらですか?

sub 0x4, %esp
push %eax                 ;;new instruction
...
call  fun                 ;; new inserted function
pop  %eax                 ;;new instruction 
.....
add 0x4, %esp
4

1 に答える 1

3

呼び出し規約は、関数の呼び出し方法、値の受け渡し方法、およびスタック スペースと使用可能なレジスタの管理方法を管理するための鍵となります。たくさんのコンベンションがあります。関数が使用しているものと、呼び出している関数が使用しているものを把握します。彼らは違うかもしれません!

非常に一般的な規則は、「独自のスタックを管理する」です。この場合、各関数は、スタック上で必要な量のスタック スペースを割り当てます。呼び出す関数のスタック スペースの需要について心配する必要はありません。定義上、必要な (追加の) 量のスタック スペースが割り当てられます。

「リーフ」関数は、他の関数を呼び出さない関数です。各リーフ関数には、ある程度のスタック スペースが必要です。一部の呼び出し規則では、リーフ関数の呼び出し元が、それ自体のニーズに合わせてスペースを割り当てるだけでなく、それが呼び出すすべてのリーフ関数のスペースを割り当てる必要があります。これにより、(最も多く呼び出される) リーフ関数を呼び出すオーバーヘッドが最小限に抑えられます。通常、この種の調整はコンパイラによってのみ行われます。これは、人々が呼び出すすべての関数とそれらの関数のスタック要求を確実に追跡することは難しいためです。場合によっては、API の一部として、呼び出し元がスペースを割り当てる必要があることを示す手書きのアセンブリ関数に遭遇することがあります。

System V ABI は、SP の下に約 128 バイトのスタックの「レッド ゾーン」を提供します。これは、リーフ関数が使用するために常に使用できます。これは、呼び出し元がそのスペースを割り当てる必要がないことを意味し、レッド ゾーン サイズの要求よりも小さいリーフ関数は、割り当てずに単に使用できるようにします。リーフ関数を呼び出しているかどうかを関数が気にする必要がないため、これは非常に優れた規則です。これにより、ルーチンの任意のセットを一緒にリンクできます。

于 2012-05-28T23:03:22.283 に答える