[ベース相対アドレシング]
lw, sw などが図 3 に示す I 形式である。
例として命令「lw $t0, 4($s0)」の 機械語による表現を図 4 に示した。 (やはり $t0 と $s0 の順番が変わる。とはいえ、この順番の変化は 重要ではない)この時、対応するメモリのアドレスは、レジスタ $s0 に格納された メモリアドレス (ベース・アドレス) に ``address フィールド" に 格納された値を加えることによって表現される。 それゆえ、このアドレシング方式をベース相対アドレシングとよぶ。
この時、アドレスフィールドは 16 ビットあるため、ベースアドレスから
バイトの範囲の値をロード・ストアできることに注意しよう。
(実際には、正負の両方があるため、
の範囲である)。
[即値アドレシング]
命令「addi $t0, $s0, 4」はレジスタ $s0 と即値 4 の和を 計算する (即値 (immediate) とは定数のことである)。 この命令は機械語では図 5 に示す即値アドレシングで 表現される。
即値には 16 ビットが割り当てられるため、 表現できる即値は[PC 相対アドレシング]
図 6 は、 レジスタ $t0 と $t1 の値が等しければ $t2 に 1 を格納し、 異なれば 0 を格納するプログラムである。 (説明のためのプログラムであり、機能的には大した意味はない)
この中で、「bne $t0,$t1,ELSE」 という命令は、 図 7 に示すような PC 相対アドレシングで表現される。
この「bne $t0,$t1,ELSE」という命令を機械語に変換する際に 問題になるのは、ラベル ELSE のアドレス (ここでは 0x400034) をどのように表現するか、ということである。
もし、ELSE を絶対的なメモリアドレス (すなわち 0x400034)
で表現するとすると、「I形式」の ``address フィールド" は 16 ビット
しか割り当てられていないため、プログラム全体は バイトで
表されねばならなくなる。今日ではこれはプログラムのサイズとしては
あまりに小さい。
そこで ELSE は、プログラムの現在の命令の位置 (Program Counter: PC) からの相対位置で表すことにする。 これが PC 相対アドレシングである。
具体的には、命令「bne $t0,$t1,ELSE」において、 プログラムの現在の位置は、 PC = 0x400028 である。 ELSE の絶対的な位置は 0x400034 であるが、 PC からの相対的な位置で表すと、12 バイト先である。 さらに、バイトでなくワード数 (語数)で表すと、 ELSE は bne 命令から 3 ワード先、ということになる。
この ``3" を命令「bne $t0,$t1,ELSE」の
``ELSE" のコーディングとしてと採用するのが、PC 相対アドレシング
である。
これは、分岐先 (ここでは ELSE) と 分岐元 (ここでは bne)
の間が 語である限りにおいてうまく行く。
この制限は、先程の「プログラムのサイズが
バイト」
という制限よりは現実的であり、実際に採用されている。
なお、現実の MIPS CPU では、分岐先を PC (ここでは 0x400028) からの
相対位置ではなく、PC (0x40002c) からの相対位置で表すが
(教科書や授業参照)、
上で見たように、MIPS シミュレータ SPIM では PC を起点として計算している
ようである。
問題