add

add

RISC-V アセンブリ 参考

lyszt.netはaddおよびその他のRISC-V命令をより詳しく扱っています。

エンコーディング形式

R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

説明

add は 2 つのレジスタの値を加算し、その結果を 3 つ目のレジスタに格納します。レジスタとはプロセッサ内部にある小さなスロットで、1 つの 32 ビット数を保持します。RISC-V は 32 個のレジスタを提供します。ビットとは 0 か 1 のことで、32 ビットは 0 からおよそ 40 億までの整数をカバーします。演算はレジスタ間で行われ、メモリに直接触れることはありません。

add は以下の形式をとり、結果は rd = rs1 + rs2 となります。rd は宛先レジスタで、答えが入ります。rs1 と rs2 はソースレジスタで、その値は変わりません。

add rd, rs1, rs2

宛先はソースとしても使えます。以下の行は t1 を t0 に加算し、結果を t0 に戻します。ループ内での累計はこの形式を使います。

add t0, t0, t1

レジスタは最大 32 ビットを保持します。合計がレジスタに保持できる最大値を超えると、結果は小さな数にラップアラウンドします。ちょうど 24 時間時計が 23:59 から 00:00 に戻るのと同じです。これがオーバーフローで、RISC-V はそれが発生しても警告を出しません。

RISC-V のマニュアルには、整数演算命令は算術例外を発生させず、基本命令セットにはオーバーフローチェックが含まれないと記載されています。これは分岐が低コストでその役割を果たすためです。符号なし加算では、add の後の 1 つの分岐で十分です。以下の 2 行では、合計がオペランドより小さいときに分岐がラベル overflow にジャンプします。これは合計がラップアラウンドした場合にのみ起こります。

add t0, t1, t2
bltu t0, t1, overflow

この例では、最初の 2 行は li (load immediate) を使って定数 3 と 4 を t0 と t1 に置きます。次に add の行が 7 を t2 に残します。

例

li t0, 3
li t1, 4
add t2, t0, t1   # t2 = 7