2012-01-06 34 views
0

私が理解している限り、スタックは、関数を実装する必要があるとき、またはレジスタを使い果たすときに使用することができます。私が持っている質問は、どのメモリが一般的に使用されているスタックなのかです。私はこれがプリフェッチプロセスやその他の要因に依存しているという印象を受けています。また、どの時点でスタッキングがRAMにロードされていますか。ASMスタックの使用

+0

あなたの質問は不明です - スタックに割り当てられたRAMの特定の領域がありません。スタックポインタについての情報 –

+0

スタックはラムです。/proc/self/maps(Linux)を見ると、仮想メモリーの一部がヒープ用にマップされた仮想メモリーの隣にスタック用にマップされ、他のジャンク用にマップされたメモリーが表示されます。スタックに関する特別なものはありません。 – Lalaland

答えて

1

すべてのプロセスにスレッドがあり、すべてのスレッドにスタックがあります。各プロセスには、プロセスアドレス空間という独自の領域があります。スレッドは、このプロセスアドレス空間にスタックを割り当てます。このスペースは仮想空間です。つまり、プロセスが4 GBのプロセス空間を取得すると、RAM上に存在するとは限りません。他のプロセスがRAMを必要とする場合、セカンダリメモリにページアウトされる可能性があります。基本的には、スタックは、セカンダリメモリ、RAM、キャッシュなどの間で移動することで、OSによって管理されるメモリであると見なして、最適な読み書き時間を最適化します。

私は主にウィンドウで作業しており、上記のステートメントはウィンドウに適しています。他のオペレーティングシステムについてはわかりません。

+0

それは私が探していた答えです。私は、あなたが作業している特定のプロセスのスタックの部分がハードディスク、RAM、またはキャッシュにあるかどうかを特定する方法があるかどうかはわかりませんでしたが、そのサウンドによって、 OSがどのようにメモリ割り当てを処理するかを書き換える。 – Blackninja543

+0

@Blackninja - スタックは非常に頻繁に使用されるため、ほとんどの場合キャッシュ内にあり、ほとんどスワップファイルには入りません。 –

+0

実行中のプロセスでは、ページフォールトが実行中のプロセス/スレッドのスタックを使用して適切なハンドラを開始する必要があるため、スタック(TOS)はスワップ可能なメモリスペースであってはなりません。しかし、中断されたプロセスのスタックは、OSの構造に応じて非常によく交換される可能性があります。 –

1

はい、一時的なストレージが必要な場合はスタックが使用されます。機能の持続時間のための記憶装置と同じくらい単純なものでも、レジスタを使い果たしたときに言及したように、それを再利用するために退去させる必要があるかもしれません。

いけないが、あまりにもはるかに簡単にどのように命令セット/ハードウェアの動作を理解するよりに巻き込ま。一般にpushおよびpopと呼ばれるこれらの命令は、一般にレジスタを取ります。通常は専用のスタックポインタレジスタで、ラムにアドレスを格納しています。プッシュが発生すると、そのレジスタのアドレスであるスタックポインタがそのデータをラムに書き込み/プッシュするために使用され、スタックポインタレジスタの内容、ラムアドレスがそれに応じて調整される。これはすべて、その命令を使用してハードウェアによって行われます。逆にポップすると、スタックポインタアドレスとポップ命令のフレーバに基づいてRAMが読み出され、RAMの内容はポップ命令のフレーバに基づいてどこかに配置され、スタックポインタレジスタの内容はそれに従って調整される。

どのようなRAMアドレスが使用され、なぜですか?あなたが求めていると思います。システムデザイナーは通常、システムでRAMを取り出し、プログラム、データ、ヒープ、スタックの間で分割します。あなたは、ラムの1つのリニアチャンクがあれば、そのラムの下位(アドレス)部分がプログラム自体を持っていて、命令の上に、そのプログラムで使用されるデータがあり、残りの部分これは誰も土地がないということです。そのメモリの一番下から上に向かって、多くの場合ヒープがどこにあるのですか。コンパイラは、mallocに必要なヒープの量を知りません。プログラマだけが行います。スタックは、このオープンスペースの上端から始まり、下に向かって成長します。スタック上に押したそれぞれのものは、最後にスタックにプッシュしたものの下にプッシュされ、下に成長します。スタックとヒープが衝突する危険性が非常に高く、それはプログラマの仕事です(通常、いくつかの言語/コンパイラは、あなたが尋ねると、それを防ぐために多くの特別なコードを焼きます)。だから一般的にスタックは、データとbssの隣にあるヒープと同じ場所にあります。確かにこれは必ずしもそうではありません。ある種の組み込みシステムではあなたのプログラムはromであり、データとヒープ(もし組み込みシステムでヒープを使用するのに十分な勇気があれば)はRAMのセクションにあります。データ/ヒープラムの隣ではなく、ラムの別のセクションにあること。そのラムは、例えばより速いからかもしれません。その良い例は、ゲームボーイアドバンテージです。チップ外にあり、一般的には遅い256Kのメモリがあり、スタックを入れて(そして重要なコードをスピードアップするのに適した)はるかに高速です。 ROMにはプログラム自体が含まれています(いくつかのハードウェアアクセラレーションがあれば痛みを伴いません)。場合によっては、6502のようなプロセッサがあります。スタック命令はRAMの特定の領域でのみ動作します。256番地は0x200番地などと考えられ、ハードウェアにそのように設計されています。オンチップではありません。 ARMモードのARMのようないくつかのプロセッサは、スタックポインタを持たず、どんなレジスタも使用でき、プッシュとポップはありません。汎用ロードとストア命令のフレーバのエイリアスです。慣例により、特定のレジスタは、しばしば、スタックポインタとしてコンパイラによって予約/使用されるが、他のプロセッサのように必須ではない。親指とthumb2のような他の武器の命令セットを与えて、命令サイズを減らし、汎用目的の性質を取り除き、従来のr13をスタックポインタとしてハードコードします。そのモードでは選択肢はありません。r13を得て、あなたは特にプッシュとポップの指示を使用します。

これをすべて実行して、Windows、Linux、またはその他のマルチスレッド/タスキングオペレーティングシステムの世界に配置します。何も変更はありません。プロセッサは、オペレーティングシステム用の命令セットのみをその場で再利用するのではなく、そのプロセッサで実行しているソフトウェアに関係なく、同じ命令セットを取得します。オペレーティングシステムは、プログラム空間、データスペース、ヒープおよびスタックが比較的少ない固定量のメモリを持つという錯覚を各プログラムに持たせるためにMMUを使用しています。 MMUは、すべてのプログラムが同じアドレス空間を持っているという錯覚を与えます。例えば、すべてのプログラムは、自分のプログラムがアドレス0x8000から始まると考えるかもしれませんし、すべてのプログラムが1つのアドレスで生きているとは思いません。0x8000は仮想アドレスです。物理アドレスと各プログラムは異なる物理アドレスセットを有する。オペレーティングシステムが次のタスク/プログラム/スレッドに切り替わると、スタックポインタと他のレジスタが保存され、次のプログラム用のレジスタがロードされ(mmuをくすぐる)、プロセッサ上で時間を与えますプログラム空間、データ空間、ヒープおよびスタックを持つ独自のフラットなメモリ空間を持っています。

スタックに関する理解の大部分は、命令セットを見ています。ストーリーの残りの部分は、スタックポインタがどのように選択されているかです。スタックポインタは、プラットフォーム、オペレーティングシステム、およびコンパイラによって異なる場合があります。多くの場合、リンカースクリプトやリンクプロセスには、ユーザー定義のルールがあります。あなたはおそらくコンパイラのデフォルトを使用しているので、プログラマ/ユーザはそれを制御できないかもしれませんが、普及しているコンパイラ(ウェルリンカ)に対しては、それを変更する選択肢があります。

関連する問題