我认为是,因为STC32G/F系列单片机已经扩充 C251指令集,实现了32位整数的四则运算(STC32G/F系列)和32位浮点数的四则运算与常用的浮点数函数(STC32F系列)。 (1)判断一个单片机芯片是几位的,可以有各种角度,我认为应该是由CPU一条机器码指令能够实现乘除法的寄存器的最高位数来定义。 比如8051 CPU,其乘除法的机器码指令的操作数是8位的寄存器,只能实现8位的乘除法,所以称之为8位单片机,哪怕乘除法的结果已经是16位的了,哪怕其内部的地址总线也已经是16位的了。 再比如8086 CPU,其乘除法的机器码指令的操作数是16位的寄存器,最多实现16位的乘除法,所以称之为16位单片机,哪怕乘除法的结果已经是32位的了,哪怕其内部的地址总线也已经是20位的了。 而且判断CPU的位数更不应该用外部总线宽度或者一次存取端口的位数来衡量,否则8086与8088就要成为不同位数的CPU架构了。 (2)现在STC32G已经实现单条指令的操作数为DR4和DR0这两个32位寄存器的乘除法运算了,未来STC32F还会实现单条指令的操作数为DR4和DR0这两个32位寄存器的32位浮点数四则运算和函数运算,所以它们事实是名符其实的32位CPU了。 单条指令的意思是不需要像CPU附加设备那样,要依靠附加其他指令来检测设备的状态位以判断操作是否完成,而是操作完成后(可以是多个机器周期)自动执行下一条指令。 (3)但是STC32G/F系列单片机属于“32位CPU”这个观点现在还不被广泛认可,有可能是由于“没有在其他的32位寄存器如DR8、DR12等上实现乘除法运算”的原因。但是我认为这种说法不成立,8051CPU也只在A和B两累加寄存器上实现。STC32G/F系列单片机继承了8051的这个传统,只累加器上实现,倒真是“32位的8051单片机”。 (4)另一个重要原因可能是STC32G/F系列单片机目前使用的主流编译器C251不支持STC对 80251指令的扩展部分。 我觉得这是个“现有鸡还是先有蛋”的问题。一般情况是Intel或者ARM这些硬件公司先在纸上设计出指令集,造出芯片,然后才有软件公司开发根据指令集造出对应的编译器,然后用它编译出机器码在单片机上运行。 目前的状况是STC通过基因改造,先制造出了32位CPU,但却没有主流的软件来支持这些32位的扩展指令。
目前STC的官方解决方法是采用设置“DMAIR”(SFR) 运算命令寄存器的方法,通过对DMAIR下命令的手段来实现这些扩展指令,我个人认为这是一个等待新编译器出世的两全其美的好方法,既可以用现有的C251编译器来,又留下了3个字节的机器码指令供今后的编译器使用。 (5)下面是扩展指令使用C251编译器的A251汇编语言的程序例子: 对于以上程序,很多人认可第7行、第10行和第11行是32位指令,但是不认可第14行和第15行是32位指令。因为它们就是两条80518位指令,根本不具有每个分号后面的想象中的“32位指令形式”。 但现实是现有Keil的C251编译器,后有STC的32位单片机,所以现版本的C251编译器不支持那两条分号后的指令是正常的,但不影响STC32G/F单片机是32位单片机的事实。
(6)不过要是我们换一个写法: 这段汇编语言程序能够通过C251的编译,能够生成正确地代码在STC32G/F单片机上运行完成每个分号后的汇编语言所示的32位加减乘除操作。 这时,你觉得分号前面的写入CODE区域的数字是不是分号后面后面的32位指令的二进制机器码?
(7)如果你还有疑惑,那么再看下面的C语言程序: 这是采用内嵌汇编语言的方式写的。Keil的C251编译器不但允许在C语言中内嵌A251汇编语言,而且允许程序员用“二进制机器码”的形式将CPU指令的二进制机器码插入程序中执行。查看编译后的LST文件,可以看到第8、9行程序产生的二进制机器码与第12、13产生的一模一样,烧录到STC单片机上都是执行分号后面的32位乘除法操作。 (8)结论:STC32G/F系列的单片机确实是32位的单片机,上面程序中的三字节的机器码确实是32位乘除法操作的二进制机器码指令,是对80251指令集的一个扩展。只是目前的Keil的C251编译器暂时还不支持这些STC扩展指令的汇编语言,也没有在自带的C语言程序库里把它们包含进去。
因此不是说它们不是32位乘除法的机器指令,只是现在只写在STC的手册上,没有作为80251的扩展指令写在Intel或者Keil的手册上而已。
|