1 RISC与CISC
1.1 RISC
ARM芯片属于精简指令集CPU(RISC: Reduced Instruction Set Computing
),它所用的指令比较简单,有如下特点:
- 对内存只有读/写指令
- 对于数据的运算在CPU内部实现
- 使用RISC指令减少复杂度
执行a = a * b
,RISC使用4条汇编指令:
- 读内存a,将数据放到处理器的寄存器中
- 读内存b,将数据放到处理器的寄存器中
- 计算a * b
- 将结果写回内存
1.2 CISC
x86属于复杂指令集计算机(CISC: Complex Instruction Set Computing
),它所用的指令比较复杂,比如某些复杂的指令,它是通过"微程序"来实现的。比如执行乘法指令时,实际上会去执行一个“微程序”,如执行a = a * b
,“微程序”内部一样执行上述四个操作,但对于程序员来说是看不见的,好像一条指令即完成。
2 流水线
Cortex-M3/4处理器使用一个3
级流水线。流水线的3个级分别是:
取指
:从存储器装载一条指令解码
(译码):识别将要被执行的指令执行
:执行处理指令并将结果写回寄存器组
取指,解码,执行是同时进行的。
当第N
条指令正在执行时,第N+2
条指令正在取指,而PC总是指向正在取指的指令,即指向第三条指令。
每次取指令都是32位的,而多数指令则是16位的,因此一次可以取两条指令,基于此可以得出以下结论(PC的LSB置1表示Thumb
状态,反之为ARM
状态):
- 处理器处于
ARM
状态时,每条指令为4
个字节,PC为当前执行的指令地址+8
字节 - 处理器处于
Thumb
状态时,每条指令为2
字节,PC为当前执行的指令地址+4
字节。(Thumb-2
指令兼有16位和32位指令,可提供几乎与ARM
指令集完全一样的功能)
[ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition]给出了说明:
为了保证Thumb-2
与Thumb
的一致性,对于CM3/4,不管执行16位或32位指令,PC总为当前执行的指令地址+4
字节。
当运行的指令大多为16位时,处理器会每隔一个周期做一次取指,因为此时CM3/4一次可取两条指令(一次能取32位),总线接口就可先“休息”一个周期再取指,若有些指令执行需要多个周期,在这期间流水线会暂停。
当执行到跳转指令时,需要清洗流水线,处理器会不得不从跳转目的地重新取指。因此,尽量地少使用跳转指令可以提高程序的执行效率。
此外,在处理器内核的预取单元中有一个指令缓冲区:
- 允许后续的指令在执行前先在里面排队
- 执行未对齐的32位指令时,避免流水线“断流”
上图即为未对齐32位Thumb-2
指令:
-
N:执行A1
-
N+4:解码B1,在指令缓冲区中执行A2
-
N+8:在指令缓冲区中解码B2,避免流水线“断流”
-
N+C:执行D,在指令缓冲区中执行C2
若缓冲区满,总线接口则处于空闲状态。
END