スタックが下向きに成長するのはなぜですか?


31

私はそれに歴史があると仮定していますが、なぜスタックが下方に成長するのですか?

スタックが上向きになった場合、バッファオーバーフローを悪用するのははるかに困難になるように思えます...


3
stackoverflow.com/questions/1677415/…は、スタックがどちらの方法でもある程度成長する可能性があることに注意します。
JBキング

6
ちょうどこのような質問があります:stackoverflow.com/questions/2035568/...が。事実、これに関するより良い質問と回答がここにあります:stackoverflow.com/questions/664744/…-
カールソン

リンクされた質問は、バッファオーバーフローの問題を完全にはカバーしていません。
-deadalnix

1
ヒープが上向きに成長するためです。
タイラー

2
メモリー位置0は上部ですか、それとも下部ですか?

回答:


21

メモリが非常に限られており、スタックで排他的に使用するためにメモリの大きなチャンクを事前に割り当てることは賢明ではなかったコンピューティングの非常に初期の時代から来ていると思います。したがって、ヒープメモリをアドレス0から上に割り当て、メモリの最後から下にスタックメモリを割り当てることにより、ヒープとスタックの両方で同じメモリ領域を共有できます。

もう少しヒープが必要な場合は、スタックの使用に注意してください。さらにスタックが必要な場合は、ヒープメモリを解放してみてください。スタックがヒープを上書きすることがあり、その逆の場合もあるため、結果はもちろん、ほとんどが壮観なクラッシュでした。

当時はインターウェブズがなかったため、バッファオーバーランの悪用の問題はありませんでした。(または、少なくともinterwebzが存在する限り、それはすべて米国国防総省の高度なセキュリティ施設内にあったため、悪意のあるデータの可能性をあまり考慮する必要はありませんでした。)

その後、ほとんどのアーキテクチャでは、同じアーキテクチャの以前のバージョンとの互換性を維持することがすべての問題でした。それが、逆さまのスタックが今日も私たちと一緒にいる理由です。


8
歴史をさかのぼると、ヒープはありませんでした。今日でも、多くの8ビットおよび16ビットのマイクロコントローラーにはヒープがありません。スタックは、プログラムを低いメモリアドレスにインストールできるように成長し、スタックは残りのメモリでした。スタックの初期化は、プログラムをロードする前に実行でき、プログラムを簡素化します。
-mattnz

1
ほとんどの小型マイクロコントローラーにはヒープがありますが、増加するヒープはありません。少量のRAM(<1Kbytes)を使用する場合、ヒープで動的メモリ割り当てを使用することを正当化するのは困難です。通常、変更される唯一のメモリセクションのサイズはスタックです。
tehnyit

7

プログラムメモリは伝統的に次のように設定されています

code
constants
heap (growing up)
...
stack (growing down)

ヒープとスタックを交換できます

しかし、スタックが他の方向に進んだ場合、バッファオーバーフローは依然として悪用される

strcpy例として古典を取り上げる

foo(char* in){
char[100] buff;
strcpy(buff,in);
}

スタックメモリとして

ret foo
arg in
buff array
ret strcpy
buf pointer
in

これは、コピーが行われたときの戻りアドレスがstrcpy(の戻りアドレスではなく)バッファの後にあり、中にあるfooものによって上書きできることを意味しますin


4

一部のハードウェアでは、ヒープがハイメモリで始まり、ダウンしていきますが、スタックはローメモリで始まります。

特にHPのPA-RISCハードウェアはこれを行います。http//www.embeddedrelated.com/usenet/embedded/show/68749-1.php

由緒あるMulticsオペレーティングシステムは、(おそらく多くの)スタックが成長したハードウェアで実行されました。http://www.acsac.org/2002/papers/classic-multics.pdfのセクション2.3.2の終わりを参照してください

第三に、Multicsプロセッサのスタックは、負の方向ではなく正の方向に成長しました。これは、実際にバッファオーバーフローを達成した場合、独自のリターンポインタではなく、未使用のスタックフレームを上書きするため、悪用がはるかに困難になることを意味します。

それはかなり興味深い声明です。バッファオーバーフローは、「通常の」プロシージャコールスタックフレームの配置が原因で、非常に大きな問題になりましたか?また、MulticsのTotally Invulnerableとしての評判は、単なるハードウェアデザインのフロックでしたか?


まあ、実行可能なスタックがないことは、おそらくMulticsがインテリジェントスタックの方向性と同じくらい助けになり、もちろん、PL / 1で書かれた多くのプログラムでは、文字列のオーバーフローも実際には問題ではありませんでした。
グレッグA.ウッズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.