これは、ベースポインターまたはスタックポインターが実際にメモリアドレスを上に移動するのではなく下に移動することを意味しますか?何故ですか?
はい、push
命令はスタックポインタをデクリメントしてスタックに書き込みpop
、逆の場合はスタックから読み取り、スタックポインタをインクリメントします。
これは、メモリが限られているマシンの場合、スタックが高く配置されて下方に拡大され、ヒープが低く配置されて上方に拡大されるという点で、やや歴史的です。「空きメモリ」のギャップは1つしかありません。ヒープとスタックの間にあり、このギャップは共有されます。どちらも個別に必要に応じてギャップに拡大できます。したがって、スタックとヒープが衝突して空きメモリがなくなると、プログラムはメモリ不足になります。
スタックとヒープの両方が同じ方向に成長する場合、2つのギャップがあり、スタックは実際にヒープのギャップに成長できません(逆もまた問題です)。
元々、プロセッサには専用のスタック処理命令がありませんでした。ただし、ハードウェアにスタックサポートが追加されたため、このパターンは下方に向かって成長し、現在でもプロセッサはこのパターンに従います。
64ビットマシンでは、複数のギャップを許可するのに十分なアドレススペースがあると主張することができます。証拠として、プロセスに複数のスレッドがある場合、複数のギャップが必然的に発生します。複数のギャップシステムでは成長の方向はほぼ任意であるため、これは物事を変える十分な動機ではありませんが、伝統/互換性は規模を傾けます。
あなたは、スタックの向きを変えるか、あるいは専用のプッシュ&ポップ命令(の使用を断念するために、指示を扱うCPUスタックを変更する必要があるだろうpush
、pop
、call
、ret
、その他)。
MIPS命令セットアーキテクチャには専用のpush
&がないpop
ため、どちらの方向にもスタックを拡張するのが実用的です。シングルスレッドプロセス用に1ギャップのメモリレイアウトが必要な場合がありますが、スタックとヒープを上に拡張できます下向き。ただし、これを行うと、一部のC 可変引数コードで、ソースまたは内部パラメータの受け渡しの調整が必要になる場合があります。
(実際、MIPSには専用のスタック処理がないため、スタックからポップするために正確な逆を使用し、また、オペレーティングシステムは、選択されたスタック使用モデルを尊重します。実際、一部の組み込みシステムおよび一部の教育システムでは、MIPSスタックが上方に拡張されています。
-4(%rbp)
ベースポインターはまったく移動せず、動作しない+4(%rbp)
可能性があることに注意してください。