2.8.2. 无符号整数除法宏示例

Example 2.10 显示了一个执行无符号整数除法的宏。 该宏采用以下四个参数:

$Bot

存放除数的寄存器。

$Top

在执行指令之前存放被除数的寄存器。 在执行指令后,该寄存器将存放余数。

$Div

存放除法的商的寄存器。 如果仅需要求余数,则该参数可以为 NULL ("")。

$Temp

在计算期间使用的临时寄存器。

Example 2.10. 


        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

该宏会检查是否任何两个参数都没有使用相同的寄存器。 如果只需要计算余数,该宏还会优化所生成的代码。

如果在汇编程序源中多次使用了 DivMod,则为了避免多次定义标签,该宏将使用局部标签 (90, 91)。 有关详细信息,请参阅局部标签

Example 2.11 显示了按如下方式调用此宏时它所生成的代码:


ratio  DivMod  r0,r5,r4,r2

Example 2.11. 


        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 © 2002-2007 ARM Limited. All rights reserved. ARM DUI 0204HC
Non-Confidential