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

📄 math32.a51

📁 实现32位数据运算! 用8051实现32位数学运算!
💻 A51
字号:
NAME    Math_32_Module
;
PUBLIC  Load_16, ?Load_16?byte
PUBLIC  Load_32, ?Load_32?byte
PUBLIC  Mul_16, ?Mul_16?byte
PUBLIC  Div_16, ?Div_16?byte
PUBLIC  Add_16, ?Add_16?byte
PUBLIC  Sub_16, ?Sub_16?byte
PUBLIC  Add_32, ?Add_32?byte
PUBLIC  Sub_32, ?Sub_32?byte
PUBLIC  Low_16, Mid_16, High_16
;
Math_32_Data    SEGMENT DATA
Math_32_Code    SEGMENT CODE
;
RSEG    Math_32_Data
?Load_16?byte:  DS 2
?Load_32?byte:  DS 4
?Mul_16?byte:   DS 2
?Div_16?byte:   DS 2
?Add_16?byte:   DS 2
?Sub_16?byte:   DS 2
?Add_32?byte:   DS 4
?Sub_32?byte:   DS 4
OP_0:           DS 1
OP_1:           DS 1
OP_2:           DS 1
OP_3:           DS 1
TMP_0:          DS 1
TMP_1:          DS 1
TMP_2:          DS 1
TMP_3:          DS 1
;
$eject
RSEG    Math_32_Code
;
Load_16:
        ;Load the lower 16 bits of the OP registers with the value supplied
        MOV     OP_3,#0
        MOV     OP_2,#0
        MOV     OP_1,?Load_16?byte
        MOV     OP_0,?Load_16?byte + 1
        RET
 
Load_32:
        ;Load all the OP registers with the value supplied
        MOV     OP_3,?Load_32?byte
        MOV     OP_2,?Load_32?byte + 1
        MOV     OP_1,?Load_32?byte + 2
        MOV     OP_0,?Load_32?byte + 3
        RET
 
Low_16:
        ;Return the lower 16 bits of the OP registers
        MOV     R6,OP_1
        MOV     R7,OP_0
        RET
 
Mid_16:
        ;Return the middle 16 bits of the OP registers
        MOV     R6,OP_2
        MOV     R7,OP_1
        RET
 
High_16:
        ;Return the high 16 bits of the OP registers
        MOV     R6,OP_3
        MOV     R7,OP_2
        RET
$eject
Add_16:
        ;Add the 16 bits supplied by the caller to the OP registers
        CLR     C
        MOV     A,OP_0
        ADDC    A,?Add_16?byte + 1      ;low byte first
        MOV     OP_0,A
        MOV     A,OP_1
        ADDC    A,?Add_16?byte          ;high byte + carry
        MOV     OP_1,A
        MOV     A,OP_2
        ADDC    A,#0                            ;propagate carry only
        MOV     OP_2,A
        MOV     A,OP_3
        ADDC    A,#0                            ;propagate carry only
        MOV     OP_3,A
        RET
 
 
Add_32:
        ;Add the 32 bits supplied by the caller to the OP registers
        CLR     C
        MOV     A,OP_0
        ADDC    A,?Add_32?byte + 3      ;lowest byte first
        MOV     OP_0,A
        MOV     A,OP_1
        ADDC    A,?Add_32?byte + 2      ;mid-lowest byte + carry
        MOV     OP_1,A
        MOV     A,OP_2
        ADDC    A,?Add_32?byte + 1      ;mid-highest byte + carry
        MOV     OP_2,A
        MOV     A,OP_3
        ADDC    A,?Add_32?byte          ;highest byte + carry
        MOV     OP_3,A
        RET
$eject
Sub_16:
        ;Subtract the 16 bits supplied by the caller from the OP registers
        CLR     C
        MOV     A,OP_0
        SUBB    A,?Sub_16?byte + 1      ;low byte first
        MOV     OP_0,A
        MOV     A,OP_1
        SUBB    A,?Sub_16?byte          ;high byte + carry
        MOV     OP_1,A
        MOV     A,OP_2
        SUBB    A,#0                            ;propagate carry only
        MOV     OP_2,A
        MOV     A,OP_3
        SUBB    A,#0                            ;propagate carry only
        MOV     OP_3,A
        RET
 
 
Sub_32:
        ;Subtract the 32 bits supplied by the caller from the OP registers
        CLR     C
        MOV     A,OP_0
        SUBB    A,?Sub_32?byte + 3      ;lowest byte first
        MOV     OP_0,A
        MOV     A,OP_1
        SUBB    A,?Sub_32?byte + 2      ;mid-lowest byte + carry
        MOV     OP_1,A
        MOV     A,OP_2
        SUBB    A,?Sub_32?byte + 1      ;mid-highest byte + carry
        MOV     OP_2,A
        MOV     A,OP_3
        SUBB    A,?Sub_32?byte          ;highest byte + carry
        MOV     OP_3,A
        RET
$eject
Mul_16:
        ;Multiply the 32 bit OP with the 16 value supplied
        MOV     TMP_3,#0        ;clear out upper 16 bits
        MOV     TMP_2,#0
        ;Generate the lowest byte of the result
        MOV     B,OP_0
        MOV     A,?Mul_16?byte+1
        MUL     AB
        MOV     TMP_0,A         ;low-order result
        MOV     TMP_1,B         ;high_order result
        ;Now generate the next higher order byte
        MOV     B,OP_1
        MOV     A,?Mul_16?byte+1
        MUL     AB
        ADD     A,TMP_1         ;low-order result
        MOV     TMP_1,A         ; save
        MOV     A,B             ; get high-order result
        ADDC    A,TMP_2         ; include carry from previous operation
        MOV     TMP_2,A         ; save
        JNC     Mul_loop1
        INC     TMP_3           ; propagate carry into TMP_3
Mul_loop1:
        MOV     B,OP_0
        MOV     A,?Mul_16?byte
        MUL     AB
        ADD     A,TMP_1         ;low-order result
        MOV     TMP_1,A         ; save
        MOV     A,B             ; get high-order result
        ADDC    A,TMP_2         ; include carry from previous operation
        MOV     TMP_2,A         ; save
        JNC     Mul_loop2
        INC     TMP_3           ; propagate carry into TMP_3
Mul_loop2:
        ; Now start working on the 3rd byte
        MOV     B,OP_2
        MOV     A,?Mul_16?byte+1
        MUL     AB
        ADD     A,TMP_2         ;low-order result
        MOV     TMP_2,A         ; save
        MOV     A,B             ; get high-order result
        ADDC    A,TMP_3         ; include carry from previous operation
        MOV     TMP_3,A         ; save
        ; Now the other half
        MOV     B,OP_1
        MOV     A,?Mul_16?byte
        MUL     AB
        ADD     A,TMP_2         ;low-order result
        MOV     TMP_2,A         ; save
        MOV     A,B             ; get high-order result
        ADDC    A,TMP_3         ; include carry from previous operation
        MOV     TMP_3,A         ; save
        ; Now finish off the highest order byte
        MOV     B,OP_3
        MOV     A,?Mul_16?byte+1
        MUL     AB
        ADD     A,TMP_3         ;low-order result
        MOV     TMP_3,A         ; save
        ; Forget about the high-order result, this is only 32 bit math!
        MOV     B,OP_2
        MOV     A,?Mul_16?byte
        MUL     AB
        ADD     A,TMP_3         ;low-order result
        MOV     TMP_3,A         ; save
        ; Now we are all done, move the TMP values back into OP
        MOV     OP_0,TMP_0
        MOV     OP_1,TMP_1
        MOV     OP_2,TMP_2
        MOV     OP_3,TMP_3
        RET
$eject
Div_16:
        ;This divides the 32 bit OP register by the value supplied
        MOV     R7,#0
        MOV     R6,#0           ;zero out partial remainder
        MOV     TMP_0,#0
        MOV     TMP_1,#0
        MOV     TMP_2,#0
        MOV     TMP_3,#0
        MOV     R1,?Div_16?byte ;load divisor
        MOV     R0,?Div_16?byte+1
        MOV     R5,#32          ;loop count
        ;This begins the loop
Div_loop:
        CALL    Shift_D         ;shift the dividend and return MSB in C
        MOV     A,R6            ;shift carry into LSB of partial remainder
        RLC     A
        MOV     R6,A
        MOV     A,R7
        RLC     A
        MOV     R7,A
        ;now test to see if R7:R6 >= R1:R0
        CLR     C
        MOV     A,R7            ;subtract R1 from R7 to see if R1 < R7
        SUBB    A,R1            ; A = R7 - R1, carry set if R7 < R1
        JC      Cant_sub
        ;at this point R7>R1 or R7=R1
        JNZ     Can_sub         ;jump if R7>R1
        ;if R7 = R1, test for R6>=R0
        CLR     C
        MOV     A,R6
        SUBB    A,R0            ; A = R6 - R0, carry set if R6 < R0
        JC      Cant_sub
Can_sub:
        ;subtract the divisor from the partial remainder
        CLR     C
        MOV     A,R6
        SUBB    A,R0            ; A = R6 - R0
        MOV     R6,A
        MOV     A,R7
        SUBB    A,R1            ; A = R7 - R1 - Borrow
        MOV     R7,A
        SETB    C               ; shift a 1 into the quotient
        JMP     Quot
Cant_sub:
        ;shift a 0 into the quotient
        CLR     C
Quot:
        ;shift the carry bit into the quotient
        CALL    Shift_Q
        ; Test for competion
        DJNZ    R5,Div_loop
        ; Now we are all done, move the TMP values back into OP
        MOV     OP_0,TMP_0
        MOV     OP_1,TMP_1
        MOV     OP_2,TMP_2
        MOV     OP_3,TMP_3
        RET
$eject
Shift_D:
        ;shift the dividend one bit to the left and return the MSB in C
        CLR     C
        MOV     A,OP_0
        RLC     A
        MOV     OP_0,A
        MOV     A,OP_1
        RLC     A
        MOV     OP_1,A
        MOV     A,OP_2
        RLC     A
        MOV     OP_2,A
        MOV     A,OP_3
        RLC     A
        MOV     OP_3,A
        RET
 
Shift_Q:
        ;shift the quotent one bit to the left and shift the C into LSB
        MOV     A,TMP_0
        RLC     A
        MOV     TMP_0,A
        MOV     A,TMP_1
        RLC     A
        MOV     TMP_1,A
        MOV     A,TMP_2
        RLC     A
        MOV     TMP_2,A
        MOV     A,TMP_3
        RLC     A
        MOV     TMP_3,A
        RET
 
        END



⌨️ 快捷键说明

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