- ベストアンサー
メモリーにも「スタック」という領域はあるの?
- 「スタック」と聞くと、CPUのレジスタのことをイメージしてしまい、メモリにはそんな領域はないと思われますが、メモリにも「スタック」領域はあるのでしょうか?
- 「コンピュータはなぜ動くのか 知っておきたいハードウエア&ソフトウエアの基礎知識」書籍内のP61には、「メモリーとCPUの入出力命令」の欄に「PUSH reg:regをスタックに書き込む」や「POP reg:スタックからregに読みだす」などの命令があることが記載されています。
- メモリーにも「スタック」領域は存在します。スタックはメモリの一部であり、データを一時的に保存するための領域です。CPUはスタックポインタと呼ばれる特殊なレジスタを使用して、スタックにデータを格納したり取り出したりします。スタックを使用することで、データの順序を保存することや関数の呼び出しを管理することができます。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
スタックポインタとスタック領域を混同されているようですね。 そもそもスタック領域はCPUにあるのではなくメモリに存在しています。スタックポインタは単にそのアドレスを指しているだけです。本に例えると、メモリが本だとすると、スタックポインタはしおりです。 ちなみに、スタック領域はハードウエアで決まっているのではなくて、ソフトウエアがメモリの一部をスタック領域として使っているに過ぎません。ハードウエアからみれば、メモリ上のどこにあろうが関係なくて、あくまでスタックポインタが指しているアドレスのデータを読み書きするだけです。PUSH、POP命令はメモリ上のデータを読み書きすると同時にスタックポインタの値を自動的に-1、+1してくれるのが便利という事ですね。
その他の回答 (7)
- hiodraiu
- ベストアンサー率15% (451/2846)
スタック領域は物理的には普通のメモリです。 CPUの初期化時に、スタックポインタが指し占めるアドレスがスタック領域の最下位アドレスになります。最上位はメモリ領域全体を設計する上で決めます。最上位を超えるとスタックオーバーフローとなります。また、マルチタスクの場合はタスクごとに、スタック領域を持ちます。
- hahaha8635
- ベストアンサー率22% (800/3610)
pop は レジスタの内容やcall などの戻ってくるアドレスを メモリ上に 書き込み スタックポインタを インクルメンタルします push は スタックポインタを ありがとうございます。あらわされた メモリをレジスタに読み込みます メモリーにはプログラム領域とデータ領域と スタック領域の区別はありません 高級言語で書かれたものは 言語上でメモリ管理されています またOS上下も管理してますので Z80の時代のように簡単には抜けませんが 使い方を間違えれば暴走します 似たようなものに ぬるぽ https://ja.wikipedia.org/wiki/%E3%81%AC%E3%82%8B%E3%81%BD 空のポインターにアクセスしようとした ハンドルの例外 https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/c01058c7-4cec-439a-be64-bd37223d7468/12495125311248912523123731242812390123561239412356203632280612?forum=vcgeneralja メモリーリーク https://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%AF などが その応用 8086 での pop/push https://vanya.jp.net/os/x86call/#pushpop 最新のi7 なども 8086系の進化来たものなので 同じことが起こります
- cwdecoder
- ベストアンサー率20% (200/997)
メモリの一部をスタックとして利用しています。 スタックポインタというレジスタの値が示すメモリ上の場所が保管場所です。
- notnot
- ベストアンサー率47% (4900/10358)
メモリーにもというか、CPU命令レベルの話でいうと、メモリにしかスタックはありません。 レジスタの「スタックポインタ」(メモリ上のスタックの先頭を示す)と混同しているのでは?
- SPROCKETER
- ベストアンサー率26% (2125/7982)
スタックというのは、SPレジスタが指し示すアドレス上のメモリー領域を意味するもので、Xレジスタが指し示すアドレス上のメモリーと理屈の上では同じものです。アキュームレータAの値をXレジスタ上のアドレスに書き込んだり、読み込んだり出来るのと同じで、アキュームレータAの値をSPレジスタ上のアドレスに書き込む(PUSH)、読み込む(POP)出来ます。PUSHやPOPすると、SPレジスタの値が自動的に-1や+1されます。 なぜスタックが必要かと言えば、レジスタの多くを使って余裕が無くなった時に、レジスタの値をスタック領域に一時退避して置いて、演算処理が終わった後でスタック領域から呼び戻す操作をおこなう時に使うものなのです。これはZ80でもCorei7でも基本的には同じです。 メモリー上のスタック領域はプログラムの先頭で定義して置くのが普通ですが、BASICから機械語に入る時にSPレジスタにセットする例が多いようです。スタック領域はRAMの最終アドレスをセットするのが望ましいのですが、RAMの後方をBASIC配列などで使っている為に、その前方にスタック領域を配置する例が多いですね。
スタックは単に保存する場所ではなく、何段でもデータを積み上げ、また積み上げたデータを新しい順番に取り出す機構です。メモリーのこの辺をスタック領域にしようと意図的に設定します。スタックへの保存、取り出しを行うPUSH、POP命令だけではなく、割込み処理やサブルーチンジャンプの際にも自動的に使われます。つまりメモリー上にスタック領域を設定し、スタックポインタSPが電源投入後にスタック領域の最上位アドレスを指しておかなければ、サブルーチンも割込みも使えません。 スタックは押入れにたくさんの布団を積むように、最後に入れたものを取り出します。メモリーアドレス07FFHから下をスタック領域にするなら、 初期化でSPスタックポインタに0800Hをセットしておく。 プログラムでPUSH AFを行うと、SPを-1する、Aレジスタの内容を(SP)アドレスに保存する、SPを-1する、Fレジスタの内容を(SP)アドレスに保存する、という動作をします。 プログラムでPOP AFを行うと、(SP)アドレスの内容をFレジスタに読む、SPを+1する、(SP)アドレスの内容をAレジスタに読む、SPを+1する、という動作をします。 これだけなら、PUSHした2バイトがPOPで戻ってくるだけですが、これを何重にも入れ子にして使うことがスタックの目的です。例えばサブルーチンにジャンプするときはCALLで自動的に現在のプログラムカウンタPCをスタックに保存し、RETで自動的にスタックから戻り先のアドレスを取り出しPCにセットします。この仕掛けのおかげで、サブルーチンの中から別のサブルーチンにジャンプしても、スタック領域が足りる限り正しい戻り先に戻ることができます。割込み処理の場合、PCの保存は自動的に行われますが、割込み処理の先頭ですべてのレジスタをPUSHし、処理の終わりですべてPOPで戻すことで、元のプログラムから見るとまるで割込み処理を実行しなかったかのように、元の処理を継続することができます。・・・って感じですがこれを読んでも分からないでしょうからネットで勉強してください。
- kimamaoyaji
- ベストアンサー率26% (2801/10379)
regはレジスターと言う物で、CPU内部の演算するための一時記憶です(論理回路的にはラッチ回路(フィリップフロップ回路が並列で複数ある回路)とかフィリップフロップ回路と言われるものです)。 初期のCPUはアキュムレーター(演算子)、やレジスターで構成されメモリをスタックメモリ(値型の変数)、ヒープメモリ(参照型の変数)という形で使います。 スタックは順番に積み重ねたという意味で、変数を入力した順番でアドレスを進めていくもの、いわゆるシーケンシャルアクセスでありヒープ(ツリー構造)ヒープ構造はメモリへのアクセスが連続しておらず、ランダムアクセスになる。 というプログラムとしての使い方でその使い方の定義が記録されている部分をスタック領域とかヒープ領域と言うだけです、物理的なRAMとしては同じですが、使い方が違う=ソフトウエア上の名前。 記憶間違えでなければそんな感じです。