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

Show/hideSee also

Copyright © 2010-2011 ARM. All rights reserved.ARM DUI 0473C
Non-ConfidentialID080411