### 5.8.2. Unsigned integer division macro example

Example 5.13 shows a macro that performs an unsigned integer division. It takes four parameters:

• `\$Bot` is the register that holds the divisor.

• `\$Top` is the register that holds the dividend before the instructions are executed. After the instructions are executed it holds the remainder.

• `\$Div` is the register where the quotient of the division is placed. It may be `NULL` ("") if only the remainder is required.

• `\$Temp` is a temporary register used during the calculation.

Example 5.13.

```		MACRO
\$Lab		DivMod		\$Div,\$Top,\$Bot,\$Temp
ASSERT		\$Top <> \$Bot						; Produce an error message if the
ASSERT		\$Top <> \$Temp						; registers supplied are
ASSERT		\$Bot <> \$Temp						; not all different.
IF		"\$Div" <> ""
ASSERT		\$Div <> \$Top					; These three only matter if \$Div
ASSERT		\$Div <> \$Bot					; is not null ("")
ASSERT		\$Div <> \$Temp					;
ENDIF
\$Lab
MOV		\$Temp, \$Bot						; Put divisor in \$Temp
CMP		\$Temp, \$Top, LSR #1						; double it until
90		MOVLS		\$Temp, \$Temp, LSL #1						; 2 * \$Temp > \$Top.
CMP		\$Temp, \$Top, LSR #1
BLS		%b90						; The b means search backwards
IF		"\$Div" <> ""						; Omit next instruction if \$Div is null
MOV		\$Div, #0					; Initialize quotient
ENDIF
91		CMP		\$Top, \$Temp						; Can we subtract \$Temp?
SUBCS		\$Top, \$Top,\$Temp						; If we can, do so.
IF		"\$Div" <> ""						; Omit next instruction if \$Div is null
ADC		\$Div, \$Div, \$Div					; Double \$Div
ENDIF
MOV		\$Temp, \$Temp, LSR #1							; Halve \$Temp,
CMP		\$Temp, \$Bot							; and loop until
BHS		%b91							; less than divisor
MEND
```

The macro checks that no two parameters use the same register. It also optimizes the code produced if only the remainder is required.

To avoid multiple definitions of labels if `DivMod` is used more than once in the assembler source, the macro uses local labels (90, 91). See Local labels of the ARM Software Development Toolkit Reference Guide.

Example 5.14 shows the code that this macro produces if it is invoked as follows:

```ratio		DivMod		r0,r5,r4,r2
```

Example 5.14.

```		ASSERT		r5 <> r4							; Produce an error if the
ASSERT		r5 <> r2							; registers supplied are
ASSERT		r4 <> r2							; not all different.
ASSERT		r0 <> r5							; These three only matter if \$Div
ASSERT		r0 <> r4							; is not null ("")
ASSERT		r0 <> r2							;
ratio
MOV		r2, r4							; Put divisor in \$Temp
CMP		r2, r5, LSR #1							; double it until
90		MOVLS		r2, r2, LSL #1							; 2 * r2 > r5.
CMP		r2, r5, LSR #1
BLS		%b90							; The b means search backwards
MOV		r0, #0							; Initialize quotient
91		CMP		r5, r2							; Can we subtract r2?
SUBCS		r5, r5, r2							; If we can, do so.
ADC		r0, r0, r0							; Double r0
MOV		r2, r2, LSR #1							; Halve r2,
CMP		r2, r4							; and loop until
BHS		%b91							; less than divisor
```