Section 14.6 Division
Algorithm 2.5.1 shows how we can compute the decimal equivalent of an int
stored in binary format. It repeatedly divides the int
by \(10\text{.}\) The remainder after each integer division is the equivalent decimal digit, starting with the low-order digits.
Many programming languages use “modulo” (‘%
’ in C) and “remainder” interchangeably. The definitions of “modulo” vary in the literature. The differences arise when dealing with negative numbers. Our use here will not use negative numbers, so it will not be an issue.
There are two simple divide instructions, sdiv
and udiv
.
SDIV
-
Divides a signed 32-bit value into another signed 32-bit value, producing a 32-bit signed result.
SDIV{<c>} <Rd>, <Rn>, <Rm>
The condition flags are not changed.
<c>
is the condition code, Table 9.2.1.<Rd>
specifies the destination register.<Rm>
contains the divisor and<Rn>
the dividend.
The value in
<Rn>
is divided by the value in<Rm>
and the result is stored in<Rd>
. All values are treated as signed values. The remainder is lost. UDIV
-
Divides an unsigned 32-bit value into another unsigned 32-bit value, producing a 32-bit unsigned result.
UDIV{<c>} <Rd>, <Rn>, <Rm>
The condition flags are not changed.
<c>
is the condition code, Table 9.2.1.<Rd>
specifies the destination register.<Rm>
contains the divisor and<Rn>
the dividend.
The value in
<Rn>
is divided by the value in<Rm>
and the result is stored in<Rd>
. All values are treated as unsigned values. The remainder is lost.
Since the divide instructions in the ARM ignore the remainder, we will need to compute it on our own in order to use Algorithm 2.5.1. The sequence of instructions:
udiv r0, r6, r7 @ no, div to get quotient mul r1, r0, r7 @ need for computing remainder sub r2, r6, r1 @ the mod (remainder)
uses the udiv
instruction to compute the quotient. The quotient is then multiplied by the divisor. Subtracting this result from the original dividend yields the remainder. Listing 14.6.1 shows how this can be done.
This algorithm produces the decimal numeral characters starting with the low-order digits. So the function stores the characters backwards
in a local char
array. It then copies the characters to the address passed by the calling function, thus reversing the string.
As discussed in the Preface, we consider only a small subset of the ARM instruction set architecture in this book. But there are many instructions that can be very useful for improving the efficiency of some computations. One such instruction is mls
which performs the multiply and subtract in one operation, thus simplifying the computation of the remainder.
MLS
-
Multiplies two 32-bit values in registers, subtracts the result from the value in a third register, and stores that in a fourth register.
MLS{<c>} <Rd>, <Rn>, <Rm>, <Ra>
The condition flags are not changed.
<c>
is the condition code, Table 9.2.1.<Rd>
specifies the destination register.<Rm>
and<Rn>
contain the multiplier and multiplicand.<Ra>
contains the minuend.
The values in
<Rm>
and<Rn>
are multiplied, the result is subtracted from the value in<Ra>
, and the result is stored in<Rd>
. Only the low-order 32 bits are retained.