单片机多字节数相乘的实现方法(转贴)

2019-04-15 11:53发布

  ****************************************************************** 1. 操作数在寄存器中,R0--R7 2. 操作数在内RAM中 3. 操作数在外RAM中 不过都大同小异,以2例,是个乘法子程序。 入口:乘数R0,被乘数R1,字节数R7,结果在R0   MULN:    LCALL  N2N                             ;多字节十六进制乘法          RLC    A          RLC    A          MOV    R3,A MULN1:   MOV    A,R5          MOV    R0,A          CLR    C          LCALL  RLCN          JNC   MULN2          LCALL   ADDN MULN2:  DJNZ   R3,MULN1 N1N:     MOV   A,R1   ADD   A,R7   MOV   R0,A   MOV   A,R7   CLR   C   RRC   A   MOV   R7,A   MOV   R2,A   ADD   A,R1   MOV   R1,A MULN3:   DEC   R0   DEC   R1   MOV   A,@R0   MOV   @R1,A   DJNZ  R2,MULN3   MOV   A,R5   MOV   R0,A   RET ; RLCN:    MOV   A,R7             ;多字节二进制无符号数左移一位 RLCN1:   MOV   R2,A          PUSH   PSW          ADD   A,R0          MOV   R0,A          POP   PSW RLCN2:   DEC   R0          MOV   A,@R0          RLC   A          MOV   @R0,A          DJNZ   R2,RLCN2          RET ; N2N:     MOV   A,R7   MOV   R2,A   ADD   A,R0   MOV   R6,A   MOV   A,R0   MOV   R5,A   MOV   A,R1   MOV   R4,A   ADD   A,R7   MOV   R0,A N2N1:    MOV   A,@R1   MOV   @R0,A   INC   R0   INC   R1   DJNZ  R2,N2N1   MOV   A,R6   MOV   R0,A   LCALL CLRN   MOV   A,R4   MOV   R0,A   LCALL CLRN   MOV   A,R4   MOV   R1,A   MOV   A,R5   MOV   R0,A   MOV   A,R7   ADD   A,R7   MOV   R7,A   RET ; ADDN:    MOV   A,R7          MOV   R2,A          ADD   A,R0          MOV   R0,A          MOV   A,R7          ADD   A,R1          MOV   R1,A          CLR   C ADN1:    DEC   R0          DEC   R1          MOV   A,@R1          ADDC  A,@R0          MOV   @R0,A          DJNZ  R2,ADN1          RET ; CLRN:    MOV   A,R7   MOV   R2,A   ADD   A,R0   MOV   R0,A   CLR   A CLRN1:   DEC   R0   MOV   @R0,A   DJNZ  R2,CLRN1   RET   比如你要把12345678H这个十六进制数乘以87654321H,那么你可以这样调用: MOV   R0,#30H     ;被乘数区 MOV   R1,#40H     ;乘数区 MOV   R7,#04H     ;字节数   MOV   30H,#12H    ;填充被乘数 MOV   31H,#34H MOV   32H,#56H MOV   33H,#78H MOV   40H,#87H    ;填充乘数 MOV   41H,#65H MOV   42H,#43H MOV   43H,#21H CALL  MULN          ;调用   这时的结果在R0所指的数据区,即30H-37H共八个字节。当然你是3字节乘法的话,把R7改成03H就可以了,   结果为6个字节,高字节在前,低字节在后。一定要注意把R0所指的区留出存放结果的空间。比如3字节乘   法,你要留出6个字节空间,5字节乘法要留出10个字节的空间。反正很灵活的。想做多少字节乘法都可以   。   这是除法子程序,入口、字节数、出口和乘法一样,不过有个限制:只限于被除数小于除数,结果为纯小   数。不知老兄是否适用。 DIVN:   LCALL  DIV0    ;多字节16进制除法子程序         JC     DIVN1         SETB   OV         RET DIVN1:  MOV    A, R0         MOV    R4, A         ADD    A, R7         MOV    R5, A         MOV    A, R7         MOV    B, #08H         MUL    AB         MOV    R3, A DIVN4:  LCALL  DIVN8         JC     DIVN5         LCALL  ADDN         CLR    C DIVN5:  MOV    A, R5         MOV    R0, A         LCALL  RLCN         DJNZ   R3,DIVN4         LCALL  DIVN8         JNC    DIVN6         MOV    A, R5         MOV    R0, A         LCALL  INCN DIVN6:  MOV    A, R1         PUSH   ACC         MOV    A, R7         MOV    R2, A         ADD    A, R4         MOV    R0, A         ADD    A, R7         MOV    R1, A DIVN7:  DEC    R0         DEC    R1         MOV    A, @R1         MOV    @R0, A         DJNZ   R2,DIVN7         POP    ACC         MOV    R1, A         CLR    OV         RET ; DIVN8:  MOV   A,R4   MOV   R0,A   CLR    C   LCALL  RLCN   MOV   2FH.4,C   LCALL  SUBN   ANL   C,/2FH.4   CPL   C   RET ; DIV0:  MOV    A,R7   MOV    R2,A   ADD    A,R1   MOV    R1,A   MOV    A,R7   ADD    A,R0   MOV    R0,A   CLR    C DIV01:  DEC    R0   DEC    R1   MOV    A,@R0   SUBB   A,@R1   DJNZ   R2,DIV01   RET ; ADDN:  MOV   A,R7   MOV   R2,A   ADD   A,R0   MOV   R0,A   MOV   A,R7   ADD   A,R1   MOV   R1,A   CLR    C ADN1:   DEC   R0   DEC   R1   MOV   A,@R1   ADDC   A,@R0   MOV   @R0,A   DJNZ   R2,ADN1   RET ; INCN:  MOV    A,R7 INCN1:  MOV    R2,A   ADD    A,R0   MOV    R0,A   SETB   C INCN2:  DEC    R0   CLR    A   ADDC   A,@R0   MOV    @R0,A   DJNZ   R2,INCN2   RET ; RLCN:  MOV   A,R7 RLCN1:  MOV   R2,A   PUSH   PSW   ADD   A,R0   MOV   R0,A   POP   PSW RLCN2:  DEC   R0   MOV   A,@R0   RLC   A   MOV   @R0,A   DJNZ   R2,RLCN2   RET ; SUBN:   MOV   A,R7   MOV   R2,A   ADD   A,R0   MOV   R0,A   MOV   A,R7   ADD   A,R1   MOV   R1,A   CLR   C SUB1:   DEC   R0   DEC   R1   MOV   A,@R0   SUBB  A,@R1   MOV   @R0,A   DJNZ  R2,SUB1   RET    ******************************************************************