演習で使用する主な MIPS 命令 - 2024年度 システムプログラミング
演習で使用する主な MIPS 命令
演習で使用する主な MIPS 命令について以下に示す.
教科書A.10「MIPS R2000 のアセンブリ言語」の命令表を補完する目的で 構成されているので,詳細は,教科書を参照されたい. また,本講義で学習しない,以下の命令については掲載していない.
- 浮動小数演算
- 割り込み例外 (syscall を除く)
凡例
Rt
,Rs
,Rd
は,$0〜$31
レジスタのいずれかが入ることを示す.Rdest
,Rsrc
など,R
の添字が 1文字より多い場合も同様であるが, 命令が擬似命令であることを示している.Imm
は即値(イミディエイト値),つまり 1 や 2 など,そのままの数値を示す.Src2
は,レジスタまたはイミディエイト値のどちらでもよいことを示す.address は,以下の形式のうちのいずれか.
(Rd)
Imm(Rd)
label
Imm
label Imm
label Imm(Rd)
上3つはよく使用する形式だが,下3つは,本演習では,あまり使用しない.
Rt[31:16]
は,Rt
レジスタの 第16ビット(0ビットから数えて17桁目)から 第31ビット(最上位ビット)の16ビット整数を示す.[u]
と付記している命令は,符号なし,あるいはオーバーフローの無しの命令があることを示す.(add
とaddu
など)
算術演算と論理演算
mnemonic | operand | 擬似コードによる説明 | 備考 |
---|---|---|---|
add[u] |
Rd, Rs, Rt |
Rd = Rs + Rt |
|
addi[u] |
Rt, Rs, Imm |
Rt = Rs + Imm |
|
and |
Rd, Rs, Rt |
Rd = Rs & Rt |
|
andi |
Rt, Rs, Imm |
Rt = Rs & Imm |
|
clo |
Rd, Rs |
Rd = Rs の上位ビットから1の続く数 |
|
clz |
Rd, Rs |
Rd = Rs の上位ビットから0の続く数 |
|
div[u] |
Rs, Rt |
lo = Rs / Rt, hi = Rs % Rt |
|
div[u] |
Rdest, Rsrc1, Rsrc2 |
Rdest = Rsrc1 / Rsrc2 |
|
mult[u] |
Rs, Rt |
lo = (Rs * Rt)[31:0], hi = (Rs * Rt)[63:32] |
|
mul |
Rd, Rs, Rt |
Rd = (Rs * Rt)[31:0] |
|
mulo[u] |
Rdest, Rsrc1, Src2 |
Rdest = (Rsrc1 * Src2)[31:0] |
|
madd[u] |
Rs, Rt |
hi:lo += Rs * Rt |
|
msub[u] |
Rs, Rt |
hi:lo -= Rs * Rt |
|
neg[u] |
Rdest, Rsrc |
Rdest = - Rsrc |
|
nor |
Rd, Rs, Rt |
Rd = ~(Rs or Rt) |
|
not |
Rdest, Rsrc |
Rdest = ~Rsrc |
|
or |
Rd, Rs, Rt |
Rd = Rs or Rt |
|
ori |
Rt, Rs, Imm |
Rt = Rs or Imm |
|
rem[u] |
Rdest, Rsrc1, Rsrc2 |
Rdest = Rsrc1 % Rsrc2 |
|
sll |
Rd, Rt, Shamt |
Rd = Rt << Shamt (論理) |
|
sllv |
Rd, Rt, Rs |
Rd = Rt << Rs (論理) |
|
sra |
Rd, Rt, Shamt |
Rd = Rt >> Shamt (算術) |
|
srav |
Rd, Rt, Rs |
Rd = Rt >> Rs (算術) |
|
srl |
Rd, Rt, Shamt |
Rd = Rt >> Shamt (論理) |
|
srlv |
Rd, Rt, Rs |
Rd = Rt >> Rs (論理) |
|
rol |
Rdest, Rsrc1, Rsrc2 |
Rdest = Rsrc1をRsrc2だけ左回転 |
|
ror |
Rdest, Rsrc1, Rsrc2 |
Rdest = Rsrc1をRsrc2だけ右回転 |
|
sub[u] |
Rd, Rs, Rt |
Rd = Rs - Rt |
|
xor |
Rd, Rs, Rt |
Rd = Rs ^ Rt |
|
xori |
Rt, Rs, Imm |
Rd = Rs ^ Imm |
定数操作命令
mnemonic | operand | 擬似コードによる説明 | 備考 |
---|---|---|---|
lui | Rt, Imm | Rt[31:16] = Imm | |
li | Rdest, Imm | Rdest = Imm |
比較命令
mnemonic | operand | 擬似コードによる説明 | 備考 |
---|---|---|---|
slt[u] | Rd, Rs, Rt | Rd = if Rs < Rt then 1 else 0 | |
slti[u] | Rt, Rs, Imm | Rt = if Rs < Imm then 1 else 0 | |
seq | Rdest, Rsrc1, Rsrc2 | Rdest = if Rsrc1 == Rsrc2 then 1 else 0 | |
sge[u] | Rdest, Rsrc1, Rsrc2 | Rdest = if Rsrc1 >= Rsrc2 then 1 else 0 | |
sgt[u] | Rdest, Rsrc1, Rsrc2 | Rdest = if Rsrc1 > Rsrc2 then 1 else 0 | |
sle[u] | Rdest, Rsrc1, Rsrc2 | Rdest = if RSrc1 <= Rsrc2 then 1 else 0 | |
sne | Rdest, Rsrc1, Rsrc2 | Rdest = if Rsrc1 != Rsrc2 then 1 else 0 |
分岐命令
mnemonic | operand | 擬似コードによる説明 | 備考 |
---|---|---|---|
b | label | goto label | j の擬似命令 |
beq | Rs, Rt, label | goto label if Rs == Rt | 16bitオフセット (2^15-1 命令前方から 2^15 命令後方) |
bgez | Rs, label | goto label if Rs >= 0 | |
bgezal | Rs, label | $ra = 次命令; goto label if Rs >= 0 | |
bgtz | Rs, label | goto label if Rs > 0 | |
blez | Rs, label | goto label if Rs <= 0 | |
bltzal | Rs, label | $ra = 次命令; goto label if Rs < 0 | |
bltz | Rs, label | goto label if Rs < 0 | |
bne | Rs, Rt, label | goto label if Rs != Rt | |
beqz | Rsrc, label | goto label if Rsrc == 0 | |
bge[u] | Rsrc1, Rsrc2, label | goto label if Rsrc1 >= Rsrc2 | |
bgt[u] | Rsrc1, Rsrc2, label | goto label if Rsrc1 > Rsrc2 | |
ble[u] | Rsrc1, Rsrc2, label | goto label if Rsrc1 <= Rsrc2 | |
blt[u] | Rsrc1, Rsrc2, label | goto label if Rsrc1 < Rsrc2 | |
bnez | Rsrc, label | goto label if Rsrc != 0 |
ジャンプ命令
mnemonic | operand | 擬似コードによる説明 | 備考 |
---|---|---|---|
j | Target | goto Target | Targetは 26bit.SPIMでは,j Rs も許される |
jal | Target | $ra = 次命令; goto Target | ジャンプ先から jr $ra で復帰できる |
jalr | Rs, Rd | Rd = 次命令; goto Rs | |
jr | Rs | goto Rs | SPIMでは,j Rs も許される |
ロード命令
mnemonic | operand | 擬似コードによる説明 | 備考 |
---|---|---|---|
la | Rdest, address | Rdest = address |
|
lb[u] | Rt, address | Rt = *((char*)address) |
8bit |
lh[u] | Rt, address | Rt = *((short*)address) |
16bit |
lw | Rt, address | Rt = *((int*)address) |
32bit |
lwl | Rt, address | address から次の4バイト境界の前までの nバイト(n = 1〜4) をRtの上位バイトから1バイトづつ埋める | |
lwr | Rt, address | address から前の4バイト境界の前までの nバイト(n = 1〜4) をRtの下位バイトから1バイトづつ埋める | |
ld | Rdest, address | Rdest = *(((int*)address) + 0), Rdest+1 = *(((int*)address) + 1) |
64bitを2つのレジスタに分割して代入 |
ulh[u] | Rdest, address | Rdest = *((short*)address) |
addressは整列化されていなくともよいが低速 |
ulw | Rdest, address | Rdest = *((int*)address) |
addressは整列化されていなくともよいが低速 |
ll | Rt, address | lw + lock | sc と対で使う (SPIMでは無意味) |
ストア命令
mnemonic | operand | 擬似コードによる説明 | 備考 |
---|---|---|---|
sb |
Rt, address |
*((char*)address) = Rt |
8bit |
sh |
Rt, address |
*((short*)address) = Rt |
16bit |
sw |
Rt, address |
*((int*)address) = Rt |
32bit |
swl |
Rt, address |
Rtの上位バイトから1バイトづつ address から次の 4バイト境界の前 nバイト(n = 1〜4) に埋める | lwl の逆 |
swr |
Rt, address |
Rtの下位バイトから1バイトづつ address から前の 4バイト境界の前 nバイト(n = 1〜4) に埋める | lwr の逆 |
sd |
Rsrc, address |
*(((int*)address) + 0) = Rsrc, *(((int*)address) + 1) = Rsrc+1 |
64bit を2つのレジスタから分割ストア |
ush |
Rsrc, address |
*((short*)address) = Rsrc |
ulh の逆 |
usw |
Rsrc, address |
*((int*)address) = Rsrc |
ulw の逆 |
sc |
Rt, address |
sw + unlock + Rt = 1 or 0 (成功/失敗) |
SPIM では無意味 |
データ転送命令
mnemonic | operand | 擬似コードによる説明 | 備考 |
---|---|---|---|
move | Rdest, Rsrc | Rdest = Rsrc | |
mfhi | Rd | Rd = hiレジスタ | hiはdivの結果の上位 |
mflo | Rd | Rd = loレジスタ | loはdivの結果の下位 |
mthi | Rs | hi = Rs | hiはdivの結果の上位 |
mtlo | Rs | lo = Rs | loはdivの結果の下位 |
movn | Rd, Rs, Rt | Rd = Rs if Rt != 0 | |
movz | Rd, Rs, Rt | Rd = Rs if Rt == 0 |
例外および割り込み
mnemonic | operand | 擬似コードによる説明 | 備考 |
---|---|---|---|
syscall | システムコールを発行する | 教科書付録A 参照 | |
break | code | code で指定される例外を発生させる | |
nop | 何もしない |