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

📄 em78 byte2mulasm.txt

📁 EM78单片机双字节乘法子程序详解及精典代码
💻 TXT
字号:
;QIUYINGDOCUMENT
; EM78 双字节的乘法
;----------------------------------------------------------------
;            (R22:R23)*(R24:R25)-->(R20:R21:R22:R23)
mul_sub:
               clr             r20           
               clr             r21
               mov             a,@16         
               mov             count,a
               bc              psw,c      
               rrc             r22
               rrc             r23                  
mul_r1:               
               jbs             psw,c                  
               jmp             mul_r2       
               mov             a,r25
               add             r21,a 
               jbc             psw,c
               inc             r20
               jbc             psw,c 
               jmp             mul_r0
               mov             a,r24        
               add             r20,a
               jmp             mul_r2 
mul_r0:               
               mov             a,r24        
               add             r20,a
               bs              psw,c       
mul_r2:
               rrc             r20           
               rrc             r21
               rrc             r22
               rrc             r23
               djz             count
               jmp             mul_r1
ret

说明: 
因为咱们ELAN没有带进位的加法,所以可能会出现一个隐藏的错误,上面给出的程序是正确的,
确实可以正常运行,理论解释也能解释明白,下面分析一个错误,详细叙述如下。

有几个地方是需要注意的,第一,高低位相加的时候,有一种情况,原来寄存器的数值是0xff
如果执行 inc 指令,那么会变成 0x00,而且进位c会置一,但是因为后面还有一条加法指令
add  r20,a ,这个加法的结果是肯定不会超过0xff (因为这里是0+ 1~0xff之间的数),所以
这条add指令之后的结果进位c铁定会变成0,那么结果出错了

试试用 0xffff  × 0xffff 就会遇到这种情况。
假设 r24r25 放被乘数,而且在运算过程中r24 r25 中的数值都比较大,加上0xff之后都会溢出
如果按照普通的C51单片机教程的乘法思想来编写的话,很容易会形成下面的程序(当然,那个编程
思想是正确的,只是说转换成ELAN语言的时候会容易犯错误。)

看下面的错误的程序:
               mov             a,r25                   ; 加上低位
               add             r21,a 
               jbc             psw,c                   ; 假设溢出了,高位加1
               inc             r20                     ; 执行inc,r20变成0x00
               mov             a,r24                   ; 加上高位
               add             r20,a                   ; 执行这指令之后 psw中的c会变成0
              
对上面的程序举个例子,假设r24=0xff ,r25=0xff ,r20=0xff ,r21=0xff
这个极端的例子来说明问题,看看程序执行之后会产生什么问题
               mov             a,r25                   ; 加上低位
               add             r21,a 

               f f
             + f f
            ---------          结果应该是3位的,最高位1保存在psw的c里面
             1 f e             r21的结果结果为 0xfe     
          ;-----------------------------------------------------------------   
               jbc             psw,c                   ; 假设溢出了,高位加1
               inc             r20                     ; 执行inc,r20变成0x00             
             因为上面计算结果溢出,所以c为1,所以执行 inc 指令

               f f
             +   1
            -------
             1 0 0             r20的结果为 0x00,溢出的 1 保存在psw的c当中 
          ;-----------------------------------------------------------------                
               mov             a,r24                   ; 加上高位
               add             r20,a                   ; 执行这指令之后 psw中的c会变成0

               0 0
             + f f 
            -------
             0 f f             由于add指令是影响psw的c位的,这个运算之后将c清掉了
         本来是  ff + 1 + ff = 1ff 的运算,由于 c位被清掉了,变成
                 ff + 1 + ff = 0ff  ,可见以上的程序是有隐藏错误的,并不是所有的计算
         都会出错,只是遇到上面说的情况的时候就会出错,一般表现为很大的两个数乘法的时候
         出现,一个比较郁闷的隐藏错误。解决办法很简单,分开两种情况处理就OK了。 

⌨️ 快捷键说明

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