5.8.2. Unsigned integer division macro example

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

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
Copyright © 1997, 1998 ARM Limited. All rights reserved.ARM DUI 0040D
Non-Confidential