8位单片机是如何进行32为数据运算的

默默进步---一鸣惊人 2017-09-18 07:46:55

大家好!本人现在有一个疑问,想请大家支支招
今天看到了stms单片机的手册中说到CPU中有一个累加器是一个8位通用目的寄存器,用于保存算术运算、逻辑运算以及数据操作的操作数及结果
那么现在假设一个函数里面要进行两个32位数据的运算比如A = B + C;(ABC都是32位的数据)
首先这3个数据在函数中是存放在栈或者数据区的,假定存在栈区(局部变量),那么在进行加法运算的过程中,CPU首先要从栈中取出相应的数,计算出结果,再把结果放到A的地址中
那么我现在不明白8位的CPU只有一个8位的累加器,如何进行运算,是一次去8位吗,还是说有其他的方式,麻烦大家帮忙解答,希望能详细点
...全文
2195 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
worldy 2017-09-21
  • 打赏
  • 举报
回复
lz可以安装一个keilc,然后简单的写写一段代码 void main() { long a=1,b=2,c; c=a+b; } 编译,输出汇编代码,研究一下汇编代码,你就知道了
of123 2017-09-20
  • 打赏
  • 举报
回复
引用 8 楼 WZJwzj123456 的回复:
这个现在没有清晰的思路,我只知道c编译器在执行移位运算的时候,会根据左值的位宽将数据扩展为左值的位宽,然后在进行移位,32位数据左移24位会把高24位移出,只留下了低8位(移位后放在了高8位),余下的低24位自动补零。这是如果左值时32位的就会保存数据,如果是16位或者8位,得到的数据就是0.
问题就在这儿。 你只有 8 位累加器的移位指令,比如说 RLC A 吧。你要对一个 Int 型数据移位。比如说 2 位,想想,你会怎么做。这个移位指令每调用一次只能左移一位,bit 8 进入 C。 你先不用考虑 C 编译器的优化算法,把指令基本用法先考虑清楚。实在想不清楚,可以看一下答案——看反汇编结果。 然后在考虑优化算法。一步一步来。 我知道什么,和我能想出什么,不是一个层次。
tianxj001 2017-09-19
  • 打赏
  • 举报
回复
引用 4 楼 WZJwzj123456 的回复:
那也就是说在数据运行的过程中32位数据的加法就是分成8位进行运算,然后保留进位标志,最后将运算得到的数据再存放到内存中是吗? 另外今天无意中发现一个问题,一个char型的数据经过左移8位后若直接赋值给一个short或者int类型的话会自动保存左移后的正常值,而赋值给char型的话就是0x00。
对于比如32位数据加法,如果内核是8位的,那么C环境编译器就会自动生成多位数加法函数,进行调用。这个在我们学习单片机C语言时候,是不需要关心的。如果你是用汇编来做,那么每一步的处理都必须由你自己编写代码来完成。包括拆字长,开寄存器,数据来回交换、计算等等。 看你第2个发现,你应该是在熟悉C环境,char左移8位,结果当然是一个int,这样赋值,本身就是C语言标准方法。 而当char左移8位再赋值给一个char的话,因为char左移8位后是一个int,根据int数据赋值给char原则,是低位直接赋值,高位扔掉。结果当然就是0,这在那个编译器上面都是这样规定的。
  • 打赏
  • 举报
回复
那也就是说在数据运行的过程中32位数据的加法就是分成8位进行运算,然后保留进位标志,最后将运算得到的数据再存放到内存中是吗? 另外今天无意中发现一个问题,一个char型的数据经过左移8位后若直接赋值给一个short或者int类型的话会自动保存左移后的正常值,而赋值给char型的话就是0x00。 char Dat = 0XFF; short NUM = 0X0000; NUM = Dat << 8;//NUM = 0XFF00 Dat <<= 8;//Dat = 0x00; 如果NUM为int型数据,则Dat << 24 后NUM的值为0XFF000000,如果左移25位NUM的值就是0XFE000000。 个人认为上述现象是跟编译器有关,大部分编译器是32位的。编译器会把数据切割成8位CPU能识别的数据,还是说移位运算也在内核中完成
of123 2017-09-19
  • 打赏
  • 举报
回复
底层肯定是使用 8-bit 运算的。 如果你使用 C 编译器,那么它已经支持多种数据类型的算术运算,包括 long 和 unsigned long 类型。它会用多条语句来实现多字节的运算。 如果你使用汇编语言,使用芯片的基础指令编程,那么,可以将这些数据看作以 8-bit 为基的多项式,进行多项式运算。
tianxj001 2017-09-19
  • 打赏
  • 举报
回复
移位指令可以说是单片机里面最奇妙的指令了,不但有简单的左右移,还有带进位位,8086 光移位指令就有8个(SAL、AHL、SAR、SHR、ROL、ROR、RCL、RCR),包括4种非循环移位和4种循环移位指令,所谓循环移位就是最高位移进最低位,原来的低7位顺移。这些,在我们进行数据变换,多位乘除法,还包括端口扫描等时候非常有用。
  • 打赏
  • 举报
回复
这个现在没有清晰的思路,我只知道c编译器在执行移位运算的时候,会根据左值的位宽将数据扩展为左值的位宽,然后在进行移位,32位数据左移24位会把高24位移出,只留下了低8位(移位后放在了高8位),余下的低24位自动补零。这是如果左值时32位的就会保存数据,如果是16位或者8位,得到的数据就是0.
of123 2017-09-19
  • 打赏
  • 举报
回复
多想比你看书强。 比如你说的移位问题,先查一下芯片的移位指令。比如 RL A 或 RLC A,都是在 8 位的累加器中左移 1 位。后者是将最高位移入了 C 标志。 你就想,现在让你来写编译器,你如何实现 int 型左移 24 或 25 位。(实际要执行 24 或 25 次移位指令。) 想想就明白了。
  • 打赏
  • 举报
回复
了解了,看来我还有很多书需要看啊,谢谢了
tianxj001 2017-09-18
  • 打赏
  • 举报
回复
嘿嘿,看错你题目了,原来你需要知道多位数据加法,那就更简单了,其实用汇编来实现的,就是低8位加,然后保留进位标志,再高8位互相带进位位相加,获得的结果,分别储存于自己定义的寄存器就可以了,这里和堆栈什么的没有半毛钱关系。更多位加法的原理也是一样进行。
tianxj001 2017-09-18
  • 打赏
  • 举报
回复
现在学习STM8等系列的单片机,貌似已经不需要用汇编来做了吧? 你问的问题,典型的汇编范围,如果你有兴趣,可以去专门的学习汇编方面的知识,当然简短的我也可以在这里告诉你。 典型的单片机一般有硬件乘法和无硬件乘法之分,以没有硬件乘法器内核的芯片来讨论,其实内部的累加器通过循环编程,很容易实现2个8位数据相乘,你可以设想一下,一个8位数据和另外一个8位数据相乘。后一个8位数据,可以拆成(1or0)*2的N次方+。。。+(1or0)*2的0次方再和被乘数相乘,恒等变换后,就是简单的移位再相加就可以了。 不过过去哪怕低档的51单片机都会有内部8X8乘法指令,结果B寄存器放结果高8位,A寄存器也即累加器放结果低8位。 扩展到更多位数,其实就需要我们开辟新的寄存器来参与运行了,利用高低段拆分,比如16位数据可以解析为8位*256+低8位。这样2个16位数据乘法就变成4段数据交叉相乘在相加就可以了,至于段之间进位,则用到了累加器的进位标志也统称进位位。 基本原理就是这样,具体的你可以参考51单片机多位数乘法的汇编。这个网上一大堆了。

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧