div

div

RISC-V アセンブリ 参考

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

説明

divは一方のレジスタを他方で除算します。ソースレジスタrs1とrs2を読み取り、最初のものを2番目のもので割り、結果を宛先レジスタrdに書き込みます。以下の形式はrd = rs1 / rs2を意味します。

div rd, rs1, rs2

乗算と同様に、これはオプションの数学命令のM拡張に属し、このシミュレータにも含まれています。

これは整数除算なので、小数部分は切り捨てられます。7を2で割ると3になります。余りの1はremから得られ、同じ2つの数値の剰余を計算します。負の結果はゼロに向かって丸められるので、-7 / 2は-3になります。

ゼロで除算すると-1が返されます。これはすべてのビットが1に設定されたレジスタです。ハードウェアは警告を出さないため、ゼロ除算をエラーとして扱う必要があるコードは、除算の前に除数をチェックします。

RISC-Vマニュアルは特殊なケースを規定しています。ゼロで除算すると、すべてのビットが設定された商が得られ、これはdivでは-1として読まれ、剰余は被除数と等しくなります。符号付きオーバーフローは、最も負の数を-1で除算した場合にのみ発生します。その場合、商は被除数と等しくなり、剰余はゼロになります。マニュアルによると、ゼロ除算でのトラップは検討されたが却下されました。それは命令セットで唯一の算術トラップになるからであり、すべてのビットを設定することで除算回路が単純に保たれるからです。

オーバーフローしない除算では、被除数は除数×商+剰余に等しくなります。商と剰余の両方が必要な場合、マニュアルは以下の2行を推奨しており、rdqはrs1およびrs2と異なる必要があります。プロセッサはその後、2つを単一の除算に融合できます。

div rdq, rs1, rs2
rem rdr, rs1, rs2

除算はプロセッサが行う最も遅い算術演算であり、多くの場合、乗算よりも何倍も遅くなります。2のべき乗(2、4、8など)での除算は、代わりに右シフトを使用できます(sraiを参照)。例では17を5で除算します。5は17に3回ちょうど入り、2が余るので、商の3がt2に入ります。

例

li t0, 17
li t1, 5
div t2, t0, t1   # t2 = 3