## Unsigned integer division macro example

Example 15 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 15. Unsigned integer division with a macro

```        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).

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

```ratio  DivMod  R0,R5,R4,R2
```

Example 16. Output from division macro

```        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
```