10、CPU指令集架构
参考资料:
目前市面上存在两种指令集架构类型:
- Reduced Instruction Set Computing (RISC) 精简指令集,比如ARM,MIPS等
- Complex Instruction Set Computing (CISC) 复杂指令集,比如Intel的X86等
简单说,一精简指令集就是只规定非常简单的2进制处理器指令,复杂的指令也只能是最基本的指令的叠加组合。二复杂指令集代表着本身就有一个很庞大的指令集库,一些复杂的指令已经在指令集库里,只需要调用即可。
当然,目前最火的当属基于RISC开发的ARM架构,在移动通信时代,凭借着低功耗打遍天下无敌手。手机,平板,自动驾驶等等等等,一招鲜吃遍天。而且RISC的构架也是ARM低功耗原因之一。RISC的CPU包含有较少的单元电路,因而面积小、功耗低;而CISC的CPU包含有丰富的电路单元,因而功能强、面积大、功耗大。
X86,依靠强有力的Intel,强势控制产业链,获取价值链上最丰厚的那部分利润.
ARM, 靠IP授权的商业模式,且技术上走与Intel差异化路线,加上一些些运气(踏对了手机这条路,谢谢TI-Nokia,Apple,Samsung for big.Little)走小而美的路线,但是凭借已经形成巨大的生态系统,占据优势.
MIPS,很学术很精美很帅,但是对指令集控制松散,导致生态系统分裂,没有形成合力,最终被市场抛弃。
下面就看一下最学术最精美的MIPS的指令集是个什么样子吧。首先了解一下CPU的工作原理,如下图:
CPU里自带几个寄存器(32位或64位),三条总线连接内存(RAM)。每一次执行指令,都包含了控制信息,地址信息,以及数据信息。而所有指令的集合就是CPU的指令集。如上图所示,左下角就是指令集,他有LOAD和STORE指令,也有数学运算指令。可以通过他们,来控制CPU和内存进行交流,比如: 从内存读取数据,CPU内部数学运算,然后存贮数据到内存。
当我们阅读 MIPS 指令时,需要理解每条指令的格式。 MIPS 指令集有三种指令格式:R 型指令,I 型指令和 J 型指令。
R 型指令
是 MIPS 指令集中用于寄存器-寄存器操作的指令格式。R 型指令由操作码(opcode)、源寄存器 1(rs)、源寄存器 2(rt)、目标寄存器(rd)、位移量(shamt)和函数码(funct)构成。
以下是 R 型指令的详细格式:
opcode rs rt rd shamt funct
其中,各个字段的含义如下:
- opcode:6 位操作码,指定执行的操作类型。
- rs:5 位源寄存器 1,操作的第一个源操作数。
- rt:5 位源寄存器 2,操作的第二个源操作数。
- rd:5 位目标寄存器,操作结果存储的目标寄存器。
- shamt:5 位位移量,用于移位操作的位移量。
- funct:6 位函数码,指定执行的具体操作。
R 型指令中的操作码 opcode
通常用于区分不同的指令类型。函数码 funct
通常用于区分同一类型指令的不同操作,这些操作可能是加、减、逻辑运算等等。
add $rd, $rs, $rt
:将$rs
和$rt
的值相加,并将结果存储在$rd
中。sub $rd, $rs, $rt
:将$rs
和$rt
的值相减,并将结果存储在$rd
中。and $rd, $rs, $rt
:将$rs
和$rt
的值进行按位与运算,并将结果存储在$rd
中。or $rd, $rs, $rt
:将$rs
和$rt
的值进行按位或运算,并将结果存储在$rd
中。slt $rd, $rs, $rt
:如果$rs
的值小于$rt
的值,则将$rd
的值设置为 1,否则设置为 0。
R 型指令在 MIPS 指令集中占据了很大的比例,它们通常用于处理寄存器之间的操作,比如算术运算、逻辑运算、移位操作等等。
I 型指令
以下是 I 型指令的详细格式:
opcode rs rt immediate
其中,各个字段的含义如下:
- opcode:6 位操作码,指定执行的操作类型。
- rs:5 位源寄存器,操作的源操作数。
- rt:5 位目标寄存器,操作结果存储的目标寄存器。
- immediate:16 位立即数,用于操作的第二个操作数或者是跳转目标地址。
I 型指令中的操作码 opcode
通常用于区分不同的指令类型。源寄存器 rs
和目标寄存器 rt
通常用于指定操作数或结果的寄存器。立即数 immediate
则用于指定一些数值或地址。
下面是一些常见的 I 型指令及其对应的操作:
addi $rt, $rs, immediate
:将$rs
和immediate
的值相加,并将结果存储在$rt
中。lw $rt, immediate($rs)
:从以$rs
为基址,偏移量为immediate
的内存地址中取出 32 位数据,并存储在$rt
中。sw $rt, immediate($rs)
:将$rt
的值存储到以$rs
为基址,偏移量为immediate
的内存地址中。beq $rs, $rt, label
:如果$rs
和$rt
的值相等,则跳转到标签为label
的地址处。bne $rs, $rt, label
:如果$rs
和$rt
的值不相等,则跳转到标签为label
的地址处。
I 型指令在 MIPS 指令集中广泛应用,通常用于处理立即数和内存数据的操作。在 MIPS 汇编语言中,立即数可以是十进制数、十六进制数或者是标签地址的偏移量。
J 型指令
是 MIPS 指令集中用于无条件跳转的指令格式。J 型指令由操作码(opcode)和跳转地址(address)构成。
以下是 J 型指令的详细格式:
opcode address
其中,各个字段的含义如下:
- opcode:6 位操作码,指定执行的操作类型。在 J 型指令中,opcode 为 2。
- address:26 位跳转地址,指定要跳转到的目标地址。
在 J 型指令中,跳转地址是指直接跳转到一个指定的地址。因此,在执行 J 型指令时,处理器会将指令寄存器 PC(程序计数器)的高 4 位与跳转地址的高 4 位相连,得到跳转后的地址,然后将其存储到 PC 中。由于跳转地址是 26 位,因此,在执行 J 型指令时,程序计数器的低 4 位会被丢弃,而需要从内存中获取跳转地址。
下面是 J 型指令的一些常见指令及其操作:
j target
:无条件跳转到目标地址,目标地址由target
指定。jal target
:无条件跳转到目标地址,并将跳转指令的下一条指令地址存储到寄存器$ra
中,以备后续返回地址的使用。
J 型指令在 MIPS 指令集中广泛应用于程序跳转,它可以用于实现条件跳转、函数调用等控制流程的操作。由于 J 型指令可以直接跳转到指定的地址,因此可以用于实现高效的跳转操作,同时也可以减少代码的执行时间和空间。
以上就是MIPS指令集的小笔记,基本上能有个初步的了解。当然,用01010101这种二进制代码写程序,可能会死人,毕竟难记还容易出错。所以大家用汇编程序来标记这些晦涩的2进制机器指令集代码,比如下面这个例子: 把数字5加上2号寄存器里面的数字,然后把结果存储到6号寄存器里。
当然人类又发明了更高级的计算机语言,比如C,C++甚至java, python, matlab等等等等, 其实只是需要用编译器把高级语言最终编译成这些010101组成的指令集指令而已,当然在编译过程中,有很多可以优化的地方。这也是为什么高级语言执行速度比较慢,而越低级的语言执行效率越快,因为越低级的语言越接近真实的机器代码。比如下面这个例子: 用c写的代码,被编译成了机器指令:
指令集是提供给处理器的一组指令,告诉处理器该怎么做以及怎么执行。在这里我不讨论特定的处理器,讨论通用处理器。
我们将指令分为数据传输指令、数据操作指令、程序控制指令,
数据传输指令,用来实现数据的传输,比如寄存器与寄存器,寄存器与内存。
数据操作指令,用来对数据进行操作,变化数据,比如有加法、位移、逻辑操作等。
程序控制指令,计算机如何执行程序,比如if,for,while等