プロが教える店舗&オフィスのセキュリティ対策術

いつもお世話になっております。独学で情報処理の勉強をしています。昨日CASLIIをキャスルツーと読むことを知ったぐらいです。「なるべく専門用語を使わないで答えてくださる方」よろしくお願いします。
基本情報午後の選択はCASLIIがいいと思って参考書を読んでみたのですが、とても難しく、ネットで検索していたら理解を深めるための記事みたいのがあったのですが、【主プログラムから副プログラムのデータの受け渡し】ということで以下のことが書かれてます。
LAD  GR1,123     ;GR1に123を格納する(主プログラムの先頭)   PUSH   0,GR1 ;123をスタックに格納する 
   LAD   GR2,456 ;GR2に456を格納する 
   PUSH   0,GR2 ;456をスタックに格納する 
   CALL   SUB1  ;副プログラムSUB1を呼び出す 
   POP   GR3    ;加算結果をスタックからGR3に取り出す
       :   ;これ以降の処理は省略する 
SUB1 POP   GR4   ;戻り番地を逃がしておく  ←これ!!
   POP   GR1    ;GR1に456を取り出す(副プログラムの先頭)   POP   GR2   ;GR2に123を取り出す 
   ADDA  GR1,GR2 ;GR1とGR2の加算結果をGR1に格納する 
    PUSH   0,GR1 ;加算結果をスタックに格納する 
    PUSH   0,GR4 ;戻り番地を元通りにする  ←ここも!!
    RET      ;主プログラムに戻る(副プログラムの末尾)
の、戻り番地を逃がしておくが意味がよく分かりません。なので、戻り番地を元通りにするもよく分かりません。
よろしくお願いします。

A 回答 (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命令を実行したときにどこに帰ればいいのかが判りませんからスタックに戻り先を格納しておくのです。

判りました?
    • good
    • 1
この回答へのお礼

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

お礼日時:2007/07/20 10:44

スタックは後から入れたものを先に取り出す方式になっているためです。


最初からスタックの中を追いかけてみましょう。
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

判ります?

この回答への補足

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

補足日時:2007/07/17 11:34
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!