sub

sub

RISC-V アセンブリ 参考

lyszt.netはsubおよびその他の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

説明

sub は、あるレジスタの値から別のレジスタの値を差し引き、その結果を 3 つ目のレジスタに書き込みます。これはレジスタに対して動作します。レジスタとは、プロセッサ内部にある番号が振られた小さな記憶領域のことで、それぞれ 1 つの 32 ビットの数値を保持します。

sub の構文は以下の通りで、結果は rd = rs1 - rs2 となります。rd は結果が格納される宛先レジスタです。rs1 および rs2 はソースレジスタです。順序は重要であり、これを逆にしてしまうのは初心者がよく犯すミスです。

sub rd, rs1, rs2

次の行は、t0 から t1 を引いた値を計算します。左側の被減数レジスタは、引き算される側です。

sub rd, rs1, rs2

定数から引き算を行うための subi 命令はありません。addi は負の定数を受け入れるため、固定された数値を引き算するには、その負の数を加算します。次の行では、t0 の値を 1 減らします。

addi t0, t0, -1

RISC-Vには、常に値0を保持するzeroという特別なレジスタがあります。zeroから数を引くと符号が反転するため、次の行ではt1の負の値をt0に格納します。neg命令は、この操作の省略形です。

sub t0, zero, t1

RISC-Vのマニュアルでは、subを rs1 から rs2 を引く演算と定義しています。オーバーフローは無視され、結果の XLEN ビット以下の部分のみが rd に書き込まれます。ここで XLEN はレジスタ幅(ビット単位)であり、この例では 32 です。 また、マニュアルには、このシミュレータで zero と名付けられているレジスタ x0 が、全ビットが 0 の値にハードワイヤードされていると記載されています。

この例では、10 から 4 を引くと、t2 には 6 が残ります。2 つのオペランドを入れ替えると -6 となり、プロセッサはこれを独自の負数表現方式で格納します。

例

li t0, 10
li t1, 4
sub t2, t0, t1   # t2 = 6