目录
一、指令集
就是汇编指令的集合
CISC 复杂指令集 代表是 Intel X86 x64
RISC 精简指令集 代表是 ARM MIPS PPC LA
二、ARM体系结构与编程
ARM Adavanced RISC Machine
RISC的特点:多数指令单周期完成
2.1 ARM的三级流水线
PC 寄存器:永远保存的是当前正在执行的指令的地址
取指 fetch PC 0X1000000C
解码 decode PC-4 0X10000008
执行 execute PC-8 0X10000004
理想状态下,假设每条指令都是单周期的。
因为CPU是并发执行的,PC指向要取出的指令(取指),与此同时,pc-4指向的指令正在被解码,pc-8指向的指令正在被执行。
指令周期数(CPI) = 单位周内执行的指令条数(理想状态下为1)
假设6个指令周期 4条指令 CPI = 6/4 = 1.5
注意:并不是流水线越长, CPU的执行效率就越高,要根据指令的平均执行周期数决定
2.2 五级流水线
计算机的体系结构有两种:
冯诺依曼: 取数据和取指令用的是同一根线
哈佛: 取数据和取指令用的不同的线
ARM9及之后的版本使用的都是哈佛体系结构
ARM9中的流水线为5级,具体讲解可参考CPU设计—五级流水线
2.3 ARM 编程模型
2.3.1 ARM的工作模式
SVC | 管理模式 | 系统上电、执行了软中断指令(SWI) |
FIQ | 快速中断 | 高优先级 |
IRQ | 中断 | 低优先级 |
Abort | 终止模式 | 非法访问存储器 |
Undef | 未定义 | 用于处理未定义的指令(非对齐访问或者地址漏洞) |
System | 系统模式 | 与用户模式共用寄存器的特权模式 |
user | 用户模式 | 应用程序的Normal |
按照不同的分类模式可分为两种:
特权模式和非特权模式 前6种为特权模式 后一种为非特权模式
异常模式和非异常模式 前5种为异常模式 后两种为正常模式
2.3.2 ARM的工作状态
ARM 工作状态 执行的是ARM指令 (word 32bit)
Thumb 工作状态 执行的是Thumb指令 (half-word 16bit)
手动切换状态:
BX Rm[0] = 1 Thumb 状态
BX Rm[0] = 0 ARM 状态
自动切换 :
注意: 只有在ARM工作状态下才能处理异常
2.3.3 ARM的寄存器结构
1、37个 32bit的寄存器
31个通用寄存器 + 6个状态寄存器
31个通用寄存器中有一个PC寄存器
6个状态寄存器 1个cpsr + 5个spsr
说白了,spsr就是cpsr的备份寄存器,cpsr:当前程序状态寄存器
在不同的工作模式和处理器状态下,程序员可以访问的寄存器也不尽相同。
2、ARM寄存器的组织结构:
寄存器和特殊功能寄存器的区别:
1) 存在的位置不同
寄存器存在ARM core 内部
特殊功能寄存器存在ARM core外部
2) 访问的方式不同
特殊功能寄存器有特定的物理地址
寄存器只有名字没有地址 很难用C访问到
3、几个重要寄存器
r0 ~ r15
r11 (fp frame pointer) 帧指针 可以忽略
r13 (sp stack pointer) 栈指针
r14 (LR 保存函数的指针)
r15 (PC 保存的是取指令的地址)
举例:
func () {
......
return
}
main () {
func (); //i++指令的地址保存到LR寄存器中
i++;
}
4、CPSR(当前程序状态寄存器)
模式位:
[4:0] 标识当前ARM core工作在哪种工作模式下
[5] T位 标识当前ARM core的工作状态 Thumb = 1 、 ARM = 0
[6] FIQ 禁止 , 写1禁止
[7] IRQ 禁止 , 写1禁止
[8:27] 保留
条件标志位:
[28] V 有符号的数据在做运算的时候有溢出 V = 1
[29] C 运算结果有进位 C = 1,借位时,C = 0
例:0xfffffffc + 10 C = 1
0x01 - 2 C = 0
[30] Z 运算结果为0 = 1
[31] N 运算结果为负数 = 1
M[4:0] | 处理器模式 |
0b10000 | 用户模式 |
0b10001 | FIQ模式 |
0b10010 | IRQ模式 |
0b10011 | 管理模式 |
0b10111 | 终止模式 |
0b11011 | 未定义模式 |
0b11111 | 系统模式 |
2.3.4 异常和异常向量表
Arm core支持5种异常:
复位异常 按下reset键, 执行swi指令 SVC
执行到了不认识的指令 undef
取指令/数据的时候, 非法访问存储器 abort
按下按键 按键中断 IRQ
高优先级的中断 FIQ
异常发生之后, 硬件上自动干4件事:
1. 备份cpsr到spsr_<mode>
2. 设置cpsr的对应的位
3. 保存异常函数的返回地址 LR_<mode> //保护现场
4. PC寄存器跳转到异常向量的入口地址
从异常返回, 软件上要干两件事:
cpsr = spsr_<mode> //恢复现场
PC = LR_<mode>
2.3.5 ARM支持的数据类型
double-word 8B
word 4B
half-word 2B
Byte 1B
2.3.6 需要汇编的情况:
系统优化
中断处理 服务程序
Debug 的时候, 分析C语言难以分析出来
初始化硬件平台
思考:为什么嵌入式开发板一上电不能直接执行C语言代码,必须要有一段汇编去初始化硬件平台?
答: 内存还没有初始化, 没有C执行的环境!
2.3.7 对齐方式
4字节对齐, 存储器的地址能被4整除
例:
struct std {
int c;
char b;
short d;
int b;
};
sizeof (struct std) = 12
三、ARM汇编
3.1 基本概念
汇编语言 又叫助记符语言
由编译器产生最佳代码
尤其是Thumb
3.2 ARM汇编指令
ARM汇编指令的特点
1) 大多数指令都是单周期
2) 大多数指令都可以条件执行 (if else / switch case)
条件执行会影响CPSR寄存器的NZCV位
条件码 :
3.3 分支跳转指令
B 分支指令
BL link 带链接的分支指令
BX 带状态切换的分支指令
B 类似C语言中的goto
注意:目标地址的范围 ±32MB
原理:根据4字节对齐
0000 0000
0004 0100
0008 1000
000C 1100
最后两位都是0
24bit的立即数就有了26位的寻址能力 ±32MB 2^26 = 64M 2^24 = 16M
1、b{cond} <target_label>
{cond} 为指令的条件码 EQ NEQ CC CS ......
<target_label> 为跳转的目标地址
例:
start:
cmp r0, r1
beq not_copy
move r0, r1
not_copy:
b .
2、BL{cond} <target_address>
例:bl main //在向main函数跳转之前, 记录当前的下条指令的地址存放到LR中
3、BX{cond} <Rm>
所谓的X就是带状态切换
Rm[0] = 1 将来跳转到的目标地址处的指令Thumb
代码中出现 代表
.code32 .arm arm指令 伪指令
.code16 .thumb thumb指令
例:
.code32
arm_code:
adr r0, thumb_code + 1
bx r0
.code16
thumb_code:
adr r0, arm_code
bx r0