|  | 
 
| 
;
×
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册  ; multiply
 ; --------
 ;
 ; 32 bit fractional multiplication.
 ; 06/03/01 v0.00 P.Everett
 ;
 ; No checks are made for overflow.
 ; To assemble, using the 'as' assembler:
 ;  as s.multiply -gcc -target SA1
 ;
 ; All have the following c declaration:
 ;  long mul(long a1, long a2);
 ;
 area    |C$$code|, CODE, READONLY
 align   4
 ;
 ; Signed fractional multiply by partial products.
 ; For use on non StrongARM machines.
 ;
 ; mul:
 ; ----
 ; Fractional multiply.
 export  |mul|
 |mul|
 stmfd   sp!,{v1,v2,v3,lr}
 ; strip signs
 cmps    a1, #0              ; check sign of input
 rsbmi   a1, a1, #0          ; create abs of input
 mvnmi   a3, #0              ; save sign,
 movpl   a3, #0              ; of input
 cmps    a2, #0              ; check sign of other input
 rsbmi   a2, a2, #0          ; create abs of other input
 mvnmi   a4, #0              ; save sign,
 movpl   a4, #0              ; of other input
 eor     v3, a3, a4          ; combine signs and save
 ; unsigned long multiply
 mov     a3, a1, lsr #16     ; Split input ,
 eor     v1, a1, a3, lsl #16 ; into two halves.
 mov     a4, a2, lsr #16     ; Split other input,
 eor     v2, a2, a4, lsl #16 ; into two halves.
 mul     a1, a3, a4          ; Produce,
 mul     a2, v1, v2          ; the,
 mul     a3, v2, a3          ; partial,
 mul     a4, v1, a4          ; products.
 adds    a2, a2, a4, lsl #16 ; Combine,
 adc     a1, a1, a4, lsr #16 ; the,
 adds    a2, a2, a3, lsl #16 ; partial,
 adc     a1, a1, a3, lsr #16 ; products.
 ; make result signed
 cmps    v3, #0              ; check result sign
 beq     |exit_a|            ; don't negate result if positive
 rsbs    a2, a2, #0          ; else negate,
 rsc     a1, a1, #0          ; the result.
 |exit_a|
 ldmfd   sp!,{v1,v2,v3,pc}^  ; return, a1 = msw of result.
 ; muls:
 ; -----
 ; Fractional multiply with single bit left shift.
 export  |muls|
 |muls|
 stmfd   sp!,{v1,v2,v3,lr}
 ; strip signs
 cmps    a1, #0              ; check sign of input
 rsbmi   a1, a1, #0          ; create abs of input
 mvnmi   a3, #0              ; save sign,
 movpl   a3, #0              ; of input
 cmps    a2, #0              ; check sign of other input
 rsbmi   a2, a2, #0          ; create abs of other input
 mvnmi   a4, #0              ; save sign,
 movpl   a4, #0              ; of other input
 eor     v3, a3, a4          ; combine signs and save
 ; unsigned long multiply
 mov     a3, a1, lsr #16     ; Split input ,
 eor     v1, a1, a3, lsl #16 ; into two halves.
 mov     a4, a2, lsr #16     ; Split other input,
 eor     v2, a2, a4, lsl #16 ; into two halves.
 mul     a1, a3, a4          ; Produce,
 mul     a2, v1, v2          ; the,
 mul     a3, v2, a3          ; partial,
 mul     a4, v1, a4          ; products.
 adds    a2, a2, a4, lsl #16 ; Combine,
 adc     a1, a1, a4, lsr #16 ; the,
 adds    a2, a2, a3, lsl #16 ; partial,
 adc     a1, a1, a3, lsr #16 ; products.
 ; make result signed
 cmps    v3, #0              ; check result sign
 beq     |exit_b|            ; don't negate result if positive
 rsbs    a2, a2, #0          ; else negate,
 rsc     a1, a1, #0          ; the result.
 |exit_b|
 ; shift and round
 movs    a2, a2, lsl #1      ; shift lsw 1 bit left,
 adc     a1, a1, a1          ; and msw, for fractional result.
 ldmfd   sp!,{v1,v2,v3,pc}^  ; return, a1 = msw of result.
 ; mulr:
 ; -----
 ; Fractional multiply with rounding.
 export  |mulr|
 |mulr|
 stmfd   sp!,{v1,v2,v3,lr}
 ; strip signs
 cmps    a1, #0              ; check sign of input
 rsbmi   a1, a1, #0          ; create abs of input
 mvnmi   a3, #0              ; save sign,
 movpl   a3, #0              ; of input
 cmps    a2, #0              ; check sign of other input
 rsbmi   a2, a2, #0          ; create abs of other input
 mvnmi   a4, #0              ; save sign,
 movpl   a4, #0              ; of other input
 eor     v3, a3, a4          ; combine signs and save
 ; unsigned long multiply
 mov     a3, a1, lsr #16     ; Split input ,
 eor     v1, a1, a3, lsl #16 ; into two halves.
 mov     a4, a2, lsr #16     ; Split other input,
 eor     v2, a2, a4, lsl #16 ; into two halves.
 mul     a1, a3, a4          ; Produce,
 mul     a2, v1, v2          ; the,
 mul     a3, v2, a3          ; partial,
 mul     a4, v1, a4          ; products.
 adds    a2, a2, a4, lsl #16 ; Combine,
 adc     a1, a1, a4, lsr #16 ; the,
 adds    a2, a2, a3, lsl #16 ; partial,
 adc     a1, a1, a3, lsr #16 ; products.
 ; make result signed
 cmps    v3, #0              ; check result sign
 beq     |exit_c|            ; don't negate result if positive
 rsbs    a2, a2, #0          ; else negate,
 rsc     a1, a1, #0          ; the result.
 |exit_c|
 ; shift and round
 adds    a2, a2, #0x80000000 ; add 1 to the bit below,
 adc     a1, a1, #0          ; the msw for rounding.
 ldmfd   sp!,{v1,v2,v3,pc}^  ; return, a1 = msw of result.
 ; mulsr:
 ; ------
 ; Fractional multiply with single bit left shift and rounding.
 export  |mulsr|
 |mulsr|
 stmfd   sp!,{v1,v2,v3,lr}
 ; strip signs
 cmps    a1, #0              ; check sign of input
 rsbmi   a1, a1, #0          ; create abs of input
 mvnmi   a3, #0              ; save sign,
 movpl   a3, #0              ; of input
 cmps    a2, #0              ; check sign of other input
 rsbmi   a2, a2, #0          ; create abs of other input
 mvnmi   a4, #0              ; save sign,
 movpl   a4, #0              ; of other input
 eor     v3, a3, a4          ; combine signs and save
 ; unsigned long multiply
 mov     a3, a1, lsr #16     ; Split input ,
 eor     v1, a1, a3, lsl #16 ; into two halves.
 mov     a4, a2, lsr #16     ; Split other input,
 eor     v2, a2, a4, lsl #16 ; into two halves.
 mul     a1, a3, a4          ; Produce,
 mul     a2, v1, v2          ; the,
 mul     a3, v2, a3          ; partial,
 mul     a4, v1, a4          ; products.
 adds    a2, a2, a4, lsl #16 ; Combine,
 adc     a1, a1, a4, lsr #16 ; the,
 adds    a2, a2, a3, lsl #16 ; partial,
 adc     a1, a1, a3, lsr #16 ; products.
 ; make result signed
 cmps    v3, #0              ; check result sign
 beq     |exit_d|            ; don't negate result if positive
 rsbs    a2, a2, #0          ; else negate,
 rsc     a1, a1, #0          ; the result.
 |exit_d|
 ; shift and round
 movs    a2, a2, lsl #1      ; shift lsw 1 bit left,
 adc     a1, a1, a1          ; and msw, for fractional result.
 adds    a2, a2, #0x80000000 ; add 1 to the bit below,
 adc     a1, a1, #0          ; the msw for rounding.
 ldmfd   sp!,{v1,v2,v3,pc}^  ; return, a1 = msw of result.
 end
 
 上面的一段汇编中,四个函数mul(), mulr(), muls(), mulsr() 均有如下函数原型:
 long func(long a1, long a2)
 由于来不及看arm的指令了,恳请熟悉arm汇编的朋友把相应的 c 函数片段写一下,或者给个提示也行,主要是移位和round的细节搞不清除。
 先谢过了。
 | 
 |