• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:戻り番地を逃がしておくの意味が分かりません)

戻り番地を逃がしておく意味がよく分かりません

このQ&Aのポイント
  • 独学で情報処理の勉強をしている方に質問です。CASLIIを学んでいる際に、【主プログラムから副プログラムのデータの受け渡し】の一環として、戻り番地を逃がしておく行為があります。しかし、この行為の意味がよく分かりません。戻り番地を逃がしておく理由を教えてください。
  • 独学で情報処理の勉強をしている方に質問です。CASLIIの選択問題に取り組んでいるのですが、副プログラムの一部に『戻り番地を逃がしておく』という記述があります。この行為の意味が分かりません。戻り番地を逃がしておく理由とは何でしょうか?
  • CASLIIの勉強をしている際に、副プログラムの一部に『戻り番地を逃がしておく』という行為があります。この行為の意味を教えてください。戻り番地を逃がしておく理由や効果について詳しく知りたいです。

質問者が選んだベストアンサー

  • ベストアンサー
noname#77845
noname#77845
回答No.2

#1です。返信が遅くなりました。 m(_ _)m 「どこにもPUSHと書いてないのになんで「1 (番地) CALLしたときの戻り番地」となるのですか。」 「CALLしたらスタックに番地をPUSHする決まりがあるのですか。」 「なんでそうする必要があるのですか。」 「具体的には番地っていくつですか。」 まずは、CASL2の仕様から見てみましょう。 1.1 (5) PR(プログラムレジスタ,Program Register) は、次に実行すべき命令語の先頭アドレスを保持している。 1.1(7)コール,リターン命令 CALL SP ←(SP)-1, (SP)←(PR), PR←実行アドレス RET PR←((SP)), SP←(SP)+1 と、なっています。 コールするときCASL2はスタックポインタの値を1すすめて、そこに今現在のプログラムレジスタの値を格納します。これは、CALL命令の次の命令をさしています。そのあと、プログラムレジスタに実行アドレス(サブルーチンの先頭アドレス)を代入しています。 事実上CALL命令はPUSHしなくてもプログラムレジスタの値をスタックに積むことができるのです。 そして、RET命令の時はスタックから元々のプログラムレジスタの値、つまりCALL命令の次の命令のアドレスを「POP」しているのです。 これで、1、2、4番目の補足質問はいいでしょうか? また、3番目の補足質問についてはサブルーチンが色々なところから呼ばれるものだというのが理由です。CALL命令で呼ばれた先はどこから呼ばれたのかは判りませんからどうにかして教えてあげないと、正しく命令を実行することができません。 例えば、110番地からCALLしたときのプログラムレジスタの値はCALL命令の次の命令を指していますが、サブルーチンにジャンプしたときは、サブルーチンの先頭アドレスを指しています。これでは、RET命令を実行したときにどこに帰ればいいのかが判りませんからスタックに戻り先を格納しておくのです。 判りました?

yoshikon
質問者

お礼

う~・・ お返事を待ち望んでいたのですが、やはり難しいです。独学で勉強しているせいか何か根本的なところが分かってないような気がします。2回も回答して頂いて分からないのも申し訳ないのですが、4回とか回答してもらって分からないともっと申し訳ないので諦めます・・。 どうもありがとうございました。

その他の回答 (1)

noname#77845
noname#77845
回答No.1

スタックは後から入れたものを先に取り出す方式になっているためです。 最初からスタックの中を追いかけてみましょう。 1 (123) PUSHしたときの値 2 不定 3 不定  ↓ 1 (456) PUSHしたときの値 2 (123) PUSHしたときの値 3 不定  ↓ 1 (番地) CALLしたときの戻り番地 2 (456) PUSHしたときの値 3 (123) PUSHしたときの値 ※ここでPOPするのですが、スタックの1番しか取り出すことができません。また、RET命令はスタックから戻り番地を取り出します。なので、実際に計算させたい値を取り出すには3回POPしないといけないのですが、最後のRET命令も考慮しなくてはいけません。 1 (456) PUSHしたときの値 → GR4に戻り番地を退避させます 2 (123) PUSHしたときの値 3 不定  ↓ ここで、2回POPして計算させます。2回POPした後のスタックは、 1 不定 2 不定 3 不定 となっています。 計算結果をPUSHします。 1 (579) PUSHしたときの値 2 不定 3 不定  ↓ GR4に退避させた戻り番地をスタックに積みます。 1 (番地) CALLしたときの戻り番地 2 (579) PUSHしたときの値 3 不定  ↓ ここで、RET命令が実行されるとスタックから番地が取り出されます。 1 (579) PUSHしたときの値 2 不定 3 不定  ↓ 計算結果をPOPします。 GR3←579 判ります?

yoshikon
質問者

補足

回答ありがとうございます。が、難しいです。 CALL SUB1 は、SUB1を呼び出すということで、どこにもPUSHと書いてないのになんで「1 (番地) CALLしたときの戻り番地」となるのですか。CALLしたらスタックに番地をPUSHする決まりがあるのですか。なんでそうする必要があるのですか。具体的には番地っていくつですか。 質問ばかりですみません。よろしくお願いします。

関連するQ&A