div
lyszt.net behandelt div und andere RISC-V-Befehle ausführlicher.
Kodierungsformat
Beschreibung
div dividiert ein Register durch ein anderes. Es liest die Quellregister rs1 und rs2, dividiert das erste durch das zweite und schreibt das Ergebnis in das Zielregister rd. Die folgende Form bedeutet rd = rs1 / rs2.
div rd, rs1, rs2
Wie die Multiplikation gehört sie zur M-Erweiterung der optionalen mathematischen Befehle, die dieser Simulator enthält.
Dies ist eine ganzzahlige Division, daher wird der Bruchteil verworfen. 7 geteilt durch 2 ergibt 3. Die übrig bleibende 1 stammt von rem, das den Rest derselben zwei Zahlen berechnet. Negative Ergebnisse runden gegen null, also ergibt -7 / 2 den Wert -3.
Die Division durch null gibt -1 zurück, ein Register, bei dem jedes Bit auf 1 gesetzt ist. Die Hardware gibt keine Warnung, daher prüft Code, der einen Nullteiler als Fehler behandeln muss, den Divisor vor der Division.
Das RISC-V-Handbuch spezifiziert die Sonderfälle. Die Division durch null ergibt einen Quotienten, bei dem jedes Bit gesetzt ist, was für div als -1 gelesen wird, und einen Rest gleich dem Dividenden. Ein vorzeichenbehafteter Überlauf tritt nur auf, wenn die negativste Zahl durch -1 dividiert wird. Der Quotient ist dann gleich dem Dividenden und der Rest ist null. Das Handbuch sagt, dass eine Falle bei der Division durch null erwogen und verworfen wurde, weil sie die einzige arithmetische Falle im Befehlssatz wäre, und dass alle gesetzten Bits die Dividierschaltung einfach halten.
Für jede Division, die nicht überläuft, ist der Dividend gleich dem Divisor mal dem Quotienten plus dem Rest. Wenn sowohl der Quotient als auch der Rest benötigt werden, empfiehlt das Handbuch die beiden folgenden Zeilen, wobei rdq von rs1 und rs2 verschieden ist. Ein Prozessor kann dann die beiden zu einer einzigen Division verschmelzen.
div rdq, rs1, rs2 rem rdr, rs1, rs2
Die Division ist die langsamste Arithmetik, die ein Prozessor ausführt, oft viele Male langsamer als die Multiplikation. Die Division durch eine Zweierpotenz (2, 4, 8 und so weiter) kann stattdessen eine Rechtsverschiebung verwenden (siehe srai). Das Beispiel dividiert 17 durch 5. Die 5 passt drei ganze Male in die 17 mit 2 übrig, also geht der Quotient 3 in t2.
Beispiel
li t0, 17 li t1, 5 div t2, t0, t1 # t2 = 3
