解決済みの質問
プログラムの起動時に、スタックメモリは初期化(NULLに設定)されるのでしょうか。
PUSH・POPで使用したらデータは残りますが、未使用の場合、初期化されているかの質問です。
グローバル変数の領域はクリアされると思われますが、スタックは不明です。
クリアされないときは、ほかのプログラムで使用されたゴミデータが
残っているのでしょうか
目的は、スタック領域でメモリ障害の場合動作が変わってしまうのか、確認したいためです。
すいませんが、よろしくお願いします。
投稿日時 - 2010-11-25 23:43:48
初期化していない変数の初期値は、言語仕様によりますが、
スタック領域に定義される変数は、たいていの言語で、初期値は不定です。
更に言えば、最後に使われた「不明」な値が残っていることでもなく、
Cの関数、JAVAのメソッドが呼び出される都度、初期値はランダムに変化するので、
「不明」ではなく、まさに「不定」です。
何故ランダムに変化するかについてですが、
まず、スタック領域の説明です。
スタック領域は、一時的な値の保存場所です。
スタックポインタによって管理されており、
スタックポインタが指しているアドレスより下(高位)は使用中、
上(低位)は使用可能となっています。
使用可能
========================== <= スタックポインタ
使用中
そして、使用可能領域は、常に割り込みルーチンにより使用されているので、
常時書き換わっています。
割り込みとは、キーが押された、マウスが動いた、通信データが受信された、
時間が経過した、等の、プログラムとは直接関係ないイベントのことで、
その発生時には、実行中のプログラムに割り込んで、
必要な処理(キーを読む、マウスポインタを動かす、通信データを読む等)を行い、
その後は何事もなかったかのように、元のプログラムの実行が継続されます。
しかし、元のプログラムの実行を継続させるためには、
割り込み時の状態をどこかに保存し、終了時には復元する必要があるわけで、
その際にスタック領域が使われます。
割り込みが発生した際のスタックの動きは以下の通りです。
- 戻りアドレスがスタックにpushされる
- フラグがスタックにpushされる
- 割り込みルーチンが呼び出される
- 保存の必要なレジスタがスタックにセーブされる
- 作業領域を確保する
- 割り込みの処理後、レジスタが復元される
- フラグが復元され、戻りアドレスに戻る、同時にスタックポインタが戻される
========================== <= 割り込み中のスタックポインタ
作業領域
--------------------------
レジスタ退避
--------------------------
フラグ
--------------------------
戻りアドレス
========================== <= 割り込み前後のスタックポインタ
使用中
話を戻しますが、プログラムでも、Cの自動変数、JAVAのローカル変数のような
一時的な変数は、スタック領域に定義されます。
C言語の例ですが、
sub(int a, int b)
{
int c,d;
の場合、関数が呼び出される際のスタックの動きは以下の通りです。
- パラメータ a, b がスタックにpushされる
- 戻りアドレスがスタックにpushされる
- 関数subが呼び出される
- 保存の必要なレジスタがスタックにセーブされる
- c, d の領域がスタックに確保される
- 関数の処理後、レジスタが復元される
- 戻りアドレスに戻る
- スタックポインタが呼び出し前の値に戻される
========================== <= 関数処理中のスタックポインタ
d
--------------------------
c
--------------------------
レジスタ退避
--------------------------
戻りアドレス
--------------------------
a
--------------------------
b
========================== <= 関数呼び出し前のスタックポインタ
使用中
c, d については、領域を確保する(スタックポインタを減らす)だけで
初期化はしないので、その時のメモリの内容が初期値になります。
そして、前述のように、使用可能なスタック領域は、
常に割り込みルーチンによって書き換えられているので、
以前の値が残っていることもなく、実行する都度、初期値が変わる「不定」です。
>目的は、スタック領域でメモリ障害の場合動作が変わってしまうのか、確認したいためです。
マルチタスクOSの場合、メモリも仮想化されているので、
プログラムが認識するメモリと物理的なメモリとは、直接の対応はないし、
メモリ障害の場合、たいていはその場でシステムダウンになります。
また、スタック領域の変数の初期値が、実行するたびに違うということなら、
スタックの性質上、それが正しい動作であり、メモリの障害ではありません。
投稿日時 - 2010-11-26 10:42:24
お礼
有難うございます。
参考にさせていただきます。
投稿日時 - 2010-11-28 14:24:22
2人が「このQ&Aが役に立った」と投票しています
ベストアンサー以外の回答(3件中 1~3件目)
OKWaveのオススメ
おすすめリンク