| ENTER ジャンプ命令 <<L1R>>,<<L1>>,<<L2>> |
【ニモニックとオペランド】
ENTER lsize, reglist
【機能】
Enter and create stack frame
手続き開始とスタックフレームの生成
【オプション】
なし
【命令フォーマットと表記法】
【解説】
高級言語用スタックフレームを作成し、レジスタを退避します。
lsizeで指定されたサイズのスタックフレームを作成し、reglistで指定されたレジスタの内容をスタックに退避します。
この命令は以下の通りに動作します。
- (1) FPの内容をスタックにプッシュ
(2) FP ← SP
(3) SP ← SP - lsize
(4) reglistで指定されたレジスタをスタックにプッシュlsizeは符号付き整数として処理されます。lsizeが小さいときは、lsizeの値を符号拡張します。lsizeが負のときは、無意味なスタックフレームが作成されます。
退避するレジスタは以下のビットマップに従ってreglistで指定します。
reglistのビット0と1(SPとFP)は常に0でなければなりません。
命令実行前と実行後のスタックの変化は以下の通りです。
一般に、高級言語のサブルーチンコールでは、以下の処理が行われます。
<サブルーチンコール>
(呼ぶ側)
1. パラメータをスタックにプッシュ( PUSH命令)
2. PCを退避して、新しいPCを設定
(呼ばれる側)
3. FPを退避して、新しいFPを設定
4. ローカル変数域を獲保
5. レジスタを退避
<サブルーチンからの復帰>
(呼ばれる側)
6. レジスタを復帰
7. ローカル変数域を解放して、FPを復帰
8. PCを復帰して呼ぶ側に戻る
(呼ぶ側)
9. スタックのパラメータを解放(SPを加算)
ステップ2はJSR命令で、3〜5はENTER命令で、6〜8はEXITD命令で実行します。
ステップ9でのパラメータの解放は呼ぶ側から行います。使用言語によっては、呼ばれる側で解放するパラメータの数が分かっていること
があります。その場合、ステップ6〜9は呼ばれる側で行うことができます。
ENTER命令を使用することにより、解放されるパラメータ数が呼ばれる側で分かっているかどうかに関係なく、プログラムを実行できます。
<呼ばれる側でパラメータの数が分からない場合>
(呼ばれる側)
6〜8 EXITD reglist, #0
(呼ぶ側)
9 ADD #N*4, SP(Nはパラメータの数)
<呼ばれる側でパラメータの数が分かっている場合>
(呼ばれる側)
6〜9 EXITD reglist, #N*4
【フラグ変化】
【発生EIT】
RIE lsize [Gen-M/r]のアドレッシングモード違反 RIE s = 1, sy = 11
【使用例】
汎用レジスタR0〜R3の領域とH'10バイトのローカル変数域からなるスタックフレームが作成されます。
![]()