?? em78 byte2mulasm.txt
字號:
;QIUYINGDOCUMENT
; EM78 雙字節(jié)的乘法
;----------------------------------------------------------------
; (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
說明:
因?yàn)樵蹅僂LAN沒有帶進(jìn)位的加法,所以可能會出現(xiàn)一個隱藏的錯誤,上面給出的程序是正確的,
確實(shí)可以正常運(yùn)行,理論解釋也能解釋明白,下面分析一個錯誤,詳細(xì)敘述如下。
有幾個地方是需要注意的,第一,高低位相加的時候,有一種情況,原來寄存器的數(shù)值是0xff
如果執(zhí)行 inc 指令,那么會變成 0x00,而且進(jìn)位c會置一,但是因?yàn)楹竺孢€有一條加法指令
add r20,a ,這個加法的結(jié)果是肯定不會超過0xff (因?yàn)檫@里是0+ 1~0xff之間的數(shù)),所以
這條add指令之后的結(jié)果進(jìn)位c鐵定會變成0,那么結(jié)果出錯了
試試用 0xffff × 0xffff 就會遇到這種情況。
假設(shè) r24r25 放被乘數(shù),而且在運(yùn)算過程中r24 r25 中的數(shù)值都比較大,加上0xff之后都會溢出
如果按照普通的C51單片機(jī)教程的乘法思想來編寫的話,很容易會形成下面的程序(當(dāng)然,那個編程
思想是正確的,只是說轉(zhuǎn)換成ELAN語言的時候會容易犯錯誤。)
看下面的錯誤的程序:
mov a,r25 ; 加上低位
add r21,a
jbc psw,c ; 假設(shè)溢出了,高位加1
inc r20 ; 執(zhí)行inc,r20變成0x00
mov a,r24 ; 加上高位
add r20,a ; 執(zhí)行這指令之后 psw中的c會變成0
對上面的程序舉個例子,假設(shè)r24=0xff ,r25=0xff ,r20=0xff ,r21=0xff
這個極端的例子來說明問題,看看程序執(zhí)行之后會產(chǎn)生什么問題
mov a,r25 ; 加上低位
add r21,a
f f
+ f f
--------- 結(jié)果應(yīng)該是3位的,最高位1保存在psw的c里面
1 f e r21的結(jié)果結(jié)果為 0xfe
;-----------------------------------------------------------------
jbc psw,c ; 假設(shè)溢出了,高位加1
inc r20 ; 執(zhí)行inc,r20變成0x00
因?yàn)樯厦嬗?jì)算結(jié)果溢出,所以c為1,所以執(zhí)行 inc 指令
f f
+ 1
-------
1 0 0 r20的結(jié)果為 0x00,溢出的 1 保存在psw的c當(dāng)中
;-----------------------------------------------------------------
mov a,r24 ; 加上高位
add r20,a ; 執(zhí)行這指令之后 psw中的c會變成0
0 0
+ f f
-------
0 f f 由于add指令是影響psw的c位的,這個運(yùn)算之后將c清掉了
本來是 ff + 1 + ff = 1ff 的運(yùn)算,由于 c位被清掉了,變成
ff + 1 + ff = 0ff ,可見以上的程序是有隱藏錯誤的,并不是所有的計(jì)算
都會出錯,只是遇到上面說的情況的時候就會出錯,一般表現(xiàn)為很大的兩個數(shù)乘法的時候
出現(xiàn),一個比較郁悶的隱藏錯誤。解決辦法很簡單,分開兩種情況處理就OK了。
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -