持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情
精简指令集和复杂指令集
20世纪70年代,IBM的John Cocke研究发现,处理器提供的大量指令集和复杂寻址方式并不会被编译器生成的代码用到:20%的简单指令经常被用到,占程序总指令数的80%;而指令集里其余80%的复杂指令很少被用到,只占程序总指令数的20%。基于这种情况,他将指令集和处理器重新进行了设计,在新的设计中只保留了常用的简单指令,这样处理器不需要浪费太多的晶体管去完成那些很复杂又很少使用的复杂指令。通常,大部分简单指令能在一个周期内完成,符合这种情况的指令集叫作精简指令集计算机(Reduced Instruction Set Computer,RISC)指令集,以前的指令集叫作复杂指令集计算机(Complex Instruction Set Computer,CISC)指令集。 IBM、加州大学伯克利分校的David Patterson以及斯坦福大学的John Hennessy是研究RISC的先驱。Power处理器来自IBM,ARM/SPARC处理器受到加州大学伯克利分校的RISC的影响,MIPS来自斯坦福大学。当前还在使用的最出名的CISC指令集是Intel/AMD的x86指令集。 RISC处理器通过更合理的微架构在性能上超越了当时传统的CISC处理器。在最初的较量中,Intel处理器败下阵来,服务器处理器的市场大部分被RISC阵营占据。Intel的David Papworth和他的同事一起设计了Pentium Pro处理器,x86指令集被译码成类似于RISC指令的微操作(micro-operations,μops)指令,以后的执行过程采用RISC内核的方式。CISC这个“古老”的架构通过巧妙的设计,又一次焕发生机,Intel的x86处理器的性能逐渐超过同期的RISC处理器。 RISC和CISC都是时代的产物,RISC在思想上更先进。
大/小端字节序
计算机操作系统是以字节为单位存储信息的,每个地址单元都对应1字节,1字节为8位。但在32位处理器中,C语言中除了8位的char类型之外,还有16位的short类型、32位的int类型。另外,对于16位、32位等位数更高的处理器,由于寄存器宽度大于1字节,必然存在如何安排多字节的问题,因此导致了大端存储模式(big-endian)和小端存储模式(little-endian)的产生。如一个16位的short类型变量X在内存中的地址为0x0010,X的值为0x1122,其中,0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,将0x22放在高地址中。小端模式则刚好相反。很多的ARM处理器默认使用小端模式,有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。Cortex-A系列的处理器可以通过软件来配置大/小端模式。大/小端模式在处理器访问内存时用于描述寄存器的字节顺序和内存中的字节顺序之间的关系。 大端模式指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。 在大端模式下,应该这样读取0x1234 5678。0000430: 1234 5678 0000 0000 0000 0000 0000 0000 0000440: 0000 0000 0000 0000 0000 0000 0100 0000 因此,大端模式下地址的增长顺序与值的增长顺序相同。 小端模式指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。 在小端模式下,应该这样读取0x1234 5678。0000430: 7856 3412 0000 0000 0000 0000 0000 0000 0000440: 0000 0000 0000 0000 0000 0000 0000 0000 因此,小端模式下地址的增长顺序与值的增长顺序相反。 从上面大/小端模式的内存视图可知,同样是读取0x1234 5678,但是该值在内存中的布局不一样。
如何判断处理器是大端模式还是小端模式?联合体(union)的存放顺序是所有成员都从低地址开始存放,利用该特性可以轻松判断CPU对内存采用大端模式还是小端模式读写。 如果以下代码的输出结果是true,则为小端模式;否则,为大端模式。
int checkCPU(void)
{
union w
{
int a;
char b;
} c;
c.a = 1;
return (c.b == 1);
}