0. 问题描述
本文包括4位二进制乘法(4位乘4位)和8位二进制除法(8位除4位)的详细计算过程。
1.创作原因
计组实验中的涉及到此问题,当时上网查阅了许多博客和资料都没能理解这两者的计算过程,并且我发现许多资料上的计算过程显得非常繁琐、晦涩,明明两三句话就可以讲明白的东西偏要说的不明不白,细节的地方忽略,计算过程示例也很少且不清楚,导致我遇到了很大困难。后来历经磨难终于理解了这两个计算过程,当时就决心要写一篇博客把这个用最简单但却最详细的话讲清楚,为后来者提供便利,少走一些弯路,多节约一些时间。
下面我们直接开始吧~
2.二进制乘法
被乘数设为5:101B
乘数设为7:111B
开始计算之前设置一个变量N保存乘法的最终结果,初始化为0。
则有详细的计算过程如下:
- 判断乘数111B的最后一位为1,则N加上被乘数,N更新为0+5=5
- 乘数右移一位更新为11B,被乘数左移一位更新为10
- 判断乘数11B最低位为1,则N加上被乘数,N更新为10+5=15
- 乘数右移一位更新为1B,被乘数左移一位更新为20
- 此时乘数1B最低位为1,则N加上被乘数,N更新为20+15=35
- 乘数右移一位更新为0,被乘数左移一位更新为40
- 此时检测乘数为0,循环结束,N的最终结果为35,即为乘法的结果
下面来总结一下整个计算过程的要点:
- 继续循环还是结束循环取决于什么时候乘数变为0
- 每一次循环中如果乘数最后一位为1则N加上被乘数;为0则不加上被乘数
下面再来看一下它的思想是什么:
我们知道 8 ∗ 8 = 16 ∗ 4 = 32 ∗ 2 = 64 ∗ 1 = 64 8*8=16*4=32*2=64*1=64 8∗8=16∗4=32∗2=64∗1=64, 这个乘法的特点就给了我们计算二进制乘法的思路,二进制中左移是乘2,右移是除2,如果被乘数左移乘数右移那么他们的乘积是不变的,即: 100 B ∗ 10 B = 1000 B ∗ 1 B = 1000 B = 8 100B*10B=1000B*1B=1000B=8 100B∗10B=1000B∗1B=1000B=8。但是如果乘数的末位为1的话不能简单地进行左移右移,设想如果不加处理乘数直接右移那么结果就会丢失掉一个被乘数的大小,这也就是为什么如果判断末位为1结果就要加上一个被乘数的原因。
8位乘8位的结果需要16位保存,其计算过程也与上方相同,只是需要涉及的寄存器更多,更加复杂一些。
3.二进制除法
被除数24:11000B
除数5:101B
开始计算前我们设置一个N表示商,其值初始化位0。
则有详细的计算过程如下:
- 将除数的最高有效位左移至与被除数的最高有效位对齐,这里将除数101B左移两位即可,除数更新为10100B
- 用被除数11000B减除数10100B,发现减得过来,因为减得过来,所以商+1,商更新为N=1。减法的结果为100B,所以被除数更新为100B
- 用被除数100B减除数10100B,发现减不过来,因为减不过来,所以除数右移一位,更新为1010B;因为除数右移一位,所以商左移一位更新为N=1*2=2 (注:左移就是与2做乘法)
- 用被除数100B减除数1010B,发现减不过来,所以除数右移一位,更新为101B;因为除数右移一位,所以商左移一位更新为N=2*2=4
- 发现现在除数的大小又变回了最开始的大小101B,则循环结束。所以现在的N=4就是除法结果,现在的被除数100B就是除法的余数
- 结束,结果正确
下面来总结一下整个计算过程的要点:
- 有许多资料可能会设置一个计数器,但我采用的的是另外的方法,和计数器其实是差不多的。除法进行到最终,除数一定要与最开始的除数相等,如果不相等则需要除数一直右移直至相等为止,相应的商也要左移同样的位数(这其实就是整除的情况)
- 循环继续还是停止取决于除数是否与最开始的除数相等
- 循环中,用被除数减除数,如果减得过来就用减法结果更新被除数并商+1;如果减不过来除数就右移一位,商左移一位
- 减不减得过来其实就看在做减法的过程中是否产生借位就可以了,在汇编语言中可以体现为标志位CF是否为1
下面我再举一个整除的例子:
被除数8:1000B
除数2:10B
计算开始:
- 除数10B左移两位,更新为1000B
- 被除数1000B减除数1000B,减得过来所以商+1,商更新为N=1;减法的结果为0所以被除数更新为0
- 被除数0减除数1000B,减不过来所以除数右移一位更新为100B,因此商左移一位更新为N=1*2=2
- 被除数0减除数100B,减不过来所以除数右移一位更新为10B,因此商左移一位更新为N=2*2=4
- 此时除数已经等于原来的除数所以循环结束,除法的商为4,余数等于此刻的被除数0
- 除法结束,结果正确
你是否对上面有一点说法有所疑惑?我在上面说到了如果什么时候除数与最开始的除数相等则结束循环,那么肯定有人会想,如果刚开始除数就不需要左移(这个时候被除数与除数位数相同),这时候是不是只进行一次循环就停止呢?
举一个除数不需要左移的例子:
被除数14:1110B
除数9:1001B
还是设除法的商为N,初始化为0。
则有详细的计算过程如下:
- 除数1001B与被除数1110B最高有效位对齐,所以无需左移
- 被除数1110B减1001B,发现减得过来,则商+1,N更新为N=0+1=1;减法结果为101B,则被除数更新为101B
- 被除数101B减除数1001B,发现减不过来,再发现此时除数与最开始的除数相等,所以除数无需右移,计算直接结束
- N=1为最终的商,被除数为101B则为除法的余数
那么上面的计算过程需要注意这些地方:
- 注意你需要在计算的什么地方判断除数是否等于最开始的除数,也就是说你需要明白你应该把判断除数这一过程放在步骤的哪一步才能让计算正确的结束,这需要思考
- 这个计算过程能够正确计算被除数小于除数的情况
它的计算思想就不细说了,在上述计算过程中都有所体现。
我用汇编语言分别实现了这两个计算过程,如下:
4.汇编实现
4.1 4乘4乘法
mov R0, #9
mov R1, #7
mov R2, #0
mov A, R0
and A, R0
jz OVER;check zero
LOOP:
mov A, R1
and A, R1
jz OVER;check zero
and A, #1
jz TAG2
mov A, R2
add A, R0
mov R2, A
TAG2:
mov A, R1
shr R1
mov A, R0
shl R0
jmp LOOP
OVER:
halt
4.1 8除4除法
mov R1, #3;除数
mov R2, #0;商
mov A, R1
mov 90, A;把除数存储起来
;计算计数器的值
JUDGE_CNT:
mov A, R1
and A, #80h
jz RM;如果是0就左移
jmp JUDGE_CNT_END
RM:
shl R1
jmp JUDGE_CNT
JUDGE_CNT_END:
mov A, R0
sub A, R1
jc ADD_BACK_MOVE;不够减加回去,除数右移
;够减商加一,被除数更新
mov R0, A
add R2, #1
ADD_BACK_MOVE:;不够减的情况
;除数右移一位
mov A, R1
sub A, 90
jz OVER;减到原除数大小结束
shr R1
shl R2
jmp JUDGE_CNT_END
OVER:
jmp OVER
4.3 说明
这两个汇编程序不是8086那套东西所以可能有不一样的地方,不用在意,大家只需要关注其中的计算过程即可。
5.ending
若有疑问可以在评论区提出一起来探讨,对你有帮助的话别忘了点赞喔~
今天的文章二进制乘法、除法的计算过程解读分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/12248.html