MIPS アセンブラーは、もともとは Christian Pirker によって書かれました。
現在、 アセンブラーと逆アセンブラーは MIPS32 アーキテクチャーの大部分をカバーしていますが、 FP 命令はサポートしていません。
レジスター名 $a0
〜$a3
は、 16 進数を隠してしまう(shadowing)のを避けるために使用できません。
代わりにレジスター番号 $4
〜$7
を使用してください。
レジスターと即値を区別するものはありません。 即値引数を持つ命令には、 i
接尾辞を付けた明示的なオペコード名を使用します。 例えば。
addu,
の代わりに addiu,
です。
アーキテクチャー・マニュアルで命令の形式が複数指定されている場合(例: jalr,
の場合)、より多くの引数を持つ形式(つまり、jalr,
の場合は 2 つ)を使用してください。 疑問がある場合は、 正しい使用例について
arch/mips/testasm.fs
を参照してください。
MIPS アーキテクチャーの分岐とジャンプには遅延スロット(delay slot)があります。 手動で入力する必要があります(最も簡単な方法は
nop,
を使用することです)。 アセンブラーは(as
とは異なり)自動的に入力しません。 if,
,
ahead,
, until,
, again,
, while,
, else,
,
repeat,
でも遅延スロットが必要です。 begin,
と then,
は分岐ターゲットを指定するだけなので影響を受けません。 ブランチの場合、 ターゲットを指定する引数は相対アドレスです。
遅延スロットのアドレスを追加して絶対アドレスを取得します。
注意: 遅延スロットに分岐やジャンプ(または制御フロー命令)を入れてはいけないことに注意してください。 また、li,
などの疑似演算を遅延スロットに入れることは、 複数の命令に拡張される可能性があるため、お勧めできません。 MIPS I
アーキテクチャーにもロード遅延スロットがあり、 新しい MIPS では依然として mfhi,
および mflo,
の使用に制限があります。 これらの制限を満たすように注意してください。 アセンブラーが自動的に制限を満たしてくれるわけではありません。
いくつかの命令の例は以下のとおりです:
$ra 12 $sp sw, \ sw ra,12(sp) $4 8 $s0 lw, \ lw a0,8(s0) $v0 $0 lui, \ lui v0,0x0 $s0 $s4 $12 addiu, \ addiu s0,s4,0x12 $s0 $s4 $4 addu, \ addu s0,s4,$a0 $ra $t9 jalr, \ jalr t9
if,
などの条件を指定するには、 条件分岐を実行し、 先頭の b
と末尾の ,
を省略します。
例えば以下のようにします:
4 5 eq if, ... \ do something if $4 equals $5 then,
32 ビット MIPS マシンの呼び出し規則では、 最初の 4 つの引数をレジスター $4
〜$7
に渡し、 戻り値に
$v0
〜$v1
を使用します。 これらのレジスターに加えて、 レジスター $t0
~ $t8
は保存・復元せずに上書きしても問題ありません。
jalr,
を使用してダイナミック・ライブラリー・ルーチンを呼び出す場合は、 最初に呼び出される関数のアドレスを $t9
にロードする必要があります。 これは、 相対メモリー・アクセスを行うために位置間接コード(position-indirect
code)によって使用されます。
MIPS32 abi-code
ワードの例を以下に示します:
abi-code my+ ( n1 n2 -- n3 ) \ SP passed in $4, returned in $v0 $t0 4 $4 lw, \ load n1, n2 from stack $t1 0 $4 lw, $t0 $t0 $t1 addu, \ add n1+n2, result in $t0 $t0 4 $4 sw, \ store result (overwriting n1) $ra jr, \ return to caller $v0 $4 4 addiu, \ (delay slot) return uptated SP in $v0 end-code