[ベース相対アドレシング]
lw, sw などが図 3 に示す I 形式である。
例として命令「lw $t0, 4($s0)」の 機械語による表現を図 4 に示した。 (やはり $t0 と $s0 の順番が変わる。とはいえ、この順番の変化は 重要ではない)この時、対応するメモリのアドレスは、レジスタ $s0 に格納された メモリアドレス (ベース・アドレス) に ``address フィールド" に 格納された値を加えることによって表現される。 それゆえ、このアドレシング方式をベース相対アドレシングとよぶ。
この時、アドレスフィールドは 16 ビットあるため、ベースアドレスから バイトの範囲の値をロード・ストアできることに注意しよう。 (実際には、正負の両方があるため、 の範囲である)。
[即値アドレシング]
命令「addi $t0, $s0, 4」はレジスタ $s0 と即値 4 の和を 計算する (即値 (immediate) とは定数のことである)。 この命令は機械語では図 5 に示す即値アドレシングで 表現される。
即値には 16 ビットが割り当てられるため、 表現できる即値は の範囲の値である (正確には、2 の補数表現した場合、 の即値を表現できる)。 定数を含んだ計算は、定数が小さい場合に多く用いられるため、 この範囲で十分である。 (大きい数を含んだ計算は、R 形式を用いればレジスタの 32 ビットを フルに使える)[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 を起点として計算している
ようである。
問題