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-2008 ARM Limited. All rights reserved.ARM DUI 0204IK
Non-Confidential