⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fmul.asm

📁 Cordic algorithm description and C/Asm51 sourcecode examples
💻 ASM
字号:
;--------------------------------------------------------------;; This routine multiplies two unsigned 16.16 fixed point       ;; numbers returning a 16.16 fixed point result.                ;                                   ;;                                                              ;; INPUT:    R0       Points to 32-bit multiplicand.            ;;           R0+4     Points to 32-bit multiplier.              ;;                                                              ;; OUTPUT:   R0       Point to high 32-bit word result          ;;                                                              ;; USES:     shift32r, shift32l                                 ;;                                                              ;; Register Usage:                                              ;;   R2      Points to Multiplicand                             ;;   R2+4    Points to Multiplier.                              ;;   R3      Points to 3rd highest word result.                 ;;   R3+4    Points to 2nd highest word result.                 ;;                                                              ;; NOTES:  This routine is based on the fact that the 32-bit    ;; value composed of bytes (x1 x2 x3 x4) multiplied by a        ;; 32-bit value (y1 y2 y3 y4) equals the 64-bit result          ;; divided into four words as follows:                          ;;                                                              ;; (x1*y1) + (x1*y2) + (x1*y3) + (x1*y4)    High word           ;; + (y1*x2) + (y1*x3) + (y1*x4)                                ;;                                                              ;; (x2*y2) + (x2*y3) + (x2*y4)              3rd highest word    ;; + (y2*x3) + (y2*x4)                                          ;; (x3*y3) + (x3*y4) + (y3*x4)              2nd highest word    ;; (x4*y4)                                  Low word            ;;                                                              ;; Since we're only allowed to return a 16.16 fixed point       ;; value, if any of the high 16-bit words are set this          ;; indicates an overflow.  The 3rd and 2nd highest 16-bit       ;; values is the actual 16.16 fixed point value returned. The   ;; low 16-bits is used to round the 2nd highest 16-bits         ;; (fractional part fixed point value) up by one if it is equal ; ; to or greater than 32,768=1000000000000000, this is easily   ;; accomplished by testing the high bit and rounding up if it   ;; is a one.                                                    ;;                                                              ;; This routine uses logical testing to determine if an         ;; overflow will occur.  This is a lot faster than multiplying  ;; the high bits to catch an overflow. There are two cases      ;; when an overflow can occur as follows:                       ;;                                                              ;;  1. (x1!=0)&&((y1!=0)||(y2!=0)||(y3!=0)||(y4!=0))            ;;  2. (y1!=0)&&((x1!=0)||(x3!=0)||(x4!=0)||(x4!=0))            ;;                                                              ;; If either of these conditions is true then C is set to       ;; indicate an error and the function is exited with no changes ;; to the input values.                                         ;;--------------------------------------------------------------;fmul:   push  0x000   push  0x001   push  0x002   push  0x003   push  0x004   push  0x005   push  0x006   push  0x007   push  dpl   push  dph   push  b   mov   r2,0x000       ; Get copy of R0 in R2; Make room on stack for 6 bytes   mov   a,sp   mov   r3,a   inc   r3             ; Save point to allocated bytes in R3   add   a,#6   mov   sp,a   ; Check high word for overflow   mov   r0,0x002       ; Get ptr 1st byte multiplicand in R0   mov   a,@r0          ; Fetch first byte   jz    fmul2          ; Zero then continue   mov   a,0x002   add   a,#4           ; Get point to multiplier in R0   mov   r0,a   sjmp  fmul3          ; Check if multiplier=0fmul2:   mov   a,0x002   add   a,#4           ; Get pointer to multiplier in R0              mov   r0,a   mov   a,@r0          ; Fetch 1st byte of multiplier   jz    fmul7          ; Zero then continue   mov   r0,0x002       ; Get pointer to multiplicand in R0fmul3:   clr   a              ; Clear logical sum   mov   b,#4           ; Get logical sum of multiplicand or multiplierfmul4:   orl   a,@r0          ; Add byte to logical sum   inc   r0             ; Point to next byte   djnz  b,fmul4        ; Loop   jnz   fmul6; Either multiplicand or multiplier=0 so return 0   mov   r0,0x002       ; Get ptr to return value   mov   b,#4fmul5:   mov   @r0,#0         ; Return 0   inc   r0   djnz  b,fmul5   clr   b              ; Indicate no error   ljmp  fmul_exitfmul6:   mov   b,#1           ; Indicate Error   ljmp  fmul_exit      ; Exitfmul7:; Get and store x2,x3,x4,y2,y3,y4 in available registers   mov   r0,0x002   inc   r0             ; Get pointer to x2   mov   a,@r0   mov   dpl,a          ; x2->DPL      inc   r0   mov   a,@r0             mov   dph,a          ; x3->DPH      inc   r0   mov   a,@r0          ; x4->R4   mov   r4,a      inc   r0   inc   r0   mov   a,@r0       mov   r5,a           ; y2->R5      inc   r0   mov   a,@r0          ; y3->R6   mov   r6,a      inc   r0   mov   a,@r0          ; y4->R7   mov   r7,a   ; Result=0   mov   r0,0x003       ; Get pointer to result   mov   b,#6fmul8:   mov   @r0,#0   inc   r0   djnz  b,fmul8      mov   r0,0x003       ; Get ptr to result in R0   ; Get (x2*y2)+(x2*y3)+(x2*y4)+(y2*x3)+(y2*x4) ; in high word result.   mov   a,dpl          ; Get x2   mov   b,r5           ; Get y2   mul   ab      lcall util_add16ab   ; High word result=x2*y2   inc   r0      mov   a,dpl          ; Get x2   mov   b,r6           ; Get y3   mul   ab   lcall util_add16ab   ; High word result += x2*y3   mov   a,r5           ; Get y2   mov   b,dph          ; Get x3   mul   ab   lcall util_add16ab   ; High word result += y2*x3   inc   r0   mov   a,dpl          ; Get x2   mov   b,r7           ; Get y4   mul   ab   lcall util_add16ab   ; High word result += x2*y4   mov   a,r5           ; Get y2   mov   b,r4           ; Get x4   mul   ab   lcall util_add16ab   ; High word result += y2*x4   mov   a,dph          ; Get x3   mov   b,r6           ; Get y3   mul   ab   lcall util_add16ab   ; Low word result += x3*y3   inc   r0      mov   a,dph          ; Get x3   mov   b,r7           ; Get y7   lcall util_add16ab   ; Low word result += x3*y4   mov   a,r6           ; Get y3   mov   b,r4           ; Get x4   mul   ab   lcall util_add16ab   ; Low word result += y3*x4   inc   r0   mov   a,r4           ; Get x4   mov   b,r7           ; Get y4   mul   ab   lcall util_add16ab   mov   a,@r0          ; Get high byte of low word   jnb   acc.7,fmul10   ; High bit=0? Yes, then continue   dec   r0             ; Point to last byte return value     ; Round up if needed.   mov   b,#4   setb  c              ; Increment by 1fmul9:   mov   a,@r0          ; Fetch byte   addc  a,#0   mov   @r0,a   dec   r0             ; Point to next byte   djnz  b,fmul9  fmul10:   mov   r0,0x003       ; Get ptr to result in R0   mov   r1,0x002       ; Get ptr to return value in R1   lcall copy32         ; Return result   clr   b              ; Indicate no error   fmul_exit:; Deallocate space on stack   mov   a,sp   clr   c   subb  a,#6   mov   sp,a   mov   a,b            ; Return error code   pop   b   pop   dph   pop   dpl   pop   0x007   pop   0x006   pop   0x005   pop   0x004   pop   0x003   pop   0x002   pop   0x001   pop   0x000   ret;--------------------------------------------------------------;; This routine adds the value in A/B to                        ;; the 16-bit value pointed to by R0.                           ;;                                                              ;; INPUT:       R0    Pointe to 16-bit value, MSB=R0, LSB=R0+1  ;;              A/B   16-bit value, B=high byte, ACC=low byte.  ;; DESTROYS:    ACC, C                                          ;;--------------------------------------------------------------;util_add16ab:   inc   r0             ; Get ptr to low byte   add   a,@r0                mov   @r0,a          ; Save low byte   dec   r0             ; Get ptr to high byte   mov   a,b            ; Get byte to add   addc  a,@r0             mov   @r0,a          ; Save high byte   ret

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -