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

 

******************************************************************

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 

 

******************************************************************

 

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值