### 2.9.2. Unsigned integer division macro example

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

`\$Bot`

The register that holds the divisor.

`\$Top`

The register that holds the dividend before the instructions are executed. After the instructions are executed, it holds the remainder.

`\$Div`

The register where the quotient of the division is placed. It can be `NULL` (`""`) if only the remainder is required.

`\$Temp`

A temporary register used during the calculation.

Example 2.14.

```        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). Refer to Local labels for more information.

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

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

Example 2.15.

```        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
```
 Copyright © 2000, 2001 ARM Limited. All rights reserved. ARM DUI 0068B Non-Confidential PDF version