《ARM Cortex-M0 权威指南》笔记(4)—指令集及应用
1. Cortex基本指令
为了将回路大小降至最低,Cortex-M0所基于的ARMv6-M体系结构只使用了16位Thumb指令和一小部分的32位Thumb指令。
Cortex-M0支持的基本16位Thumb指令:
Cortex-M0 支持多个基于Thumb-2技术的32位Thumb指令。
MRS和MSR,特殊寄存器访问指令;
LSB、DSB和DMB,存储器同步指令;
BL指令(BL被包含在传统的Thumb指令集中,而其位域定义在Thumb-2中得到扩展)
关于指令细节,参考书籍《DDI0419C_arm_architecture_v6m_reference_manual》
2. 汇编基础
根据功能可以将Cortex-M0处理器的指令划分为以下几组:
在处理器内移动数据
存储器访问
栈空间访问
算术运算
逻辑运算
移位和循环操作
展开和顺序反转操作
程序流程控制(跳转、条件跳转和函数调用)
存储器屏蔽指令
异常相关指令
休眠模式特性相关指令
其他功能
2.1 存储器访问
Cortex-M0 处理器支持多个存储器访问指令,并且支持各种宽度的数据传输和寻址方式。可以使用的数据宽度包括字(4字节)、半字(2字节)和字节,另外对有符号和无符号数,还有不同的指令。
重要提醒:
进行存储访问时,应确保地址是对齐的。例如,执行字访问需要操作地址的最低两位为0,半字访问则需要操作地址的最低为0。
2.2 栈空间访问
栈空间访问可以通过两个专用存储器访问指令执行,PUSH指令用于减小当前栈指针并且将数据存储到栈中,POP指令则从栈中读出数据并且增加当前的栈指针。
2.3 程序流程控制
Cortex-M0处理器支持5个跳转指令(B、B<cond>(条件跳转)、BL(跳转并链接)、BX(跳转并交换)、BLX(跳转链接并交换))。他们对于诸如循环及条件执行等程序流控制尤其重要,并且还可以用于将程序代码划分为函数和子程序。
BL通常用于函数或子程序的调用。执行BL时,下一条指令的地址会被存储到链接寄存器(LR)中,并且最低置1。当函数或子函数完成指定的任务后,可以通过执行"BX LR"指令返回到调用程序。
2.4 异常相关指令
Cortex-M0 处理器中包含了一条被称为请求管理(SVC)的指令。如果SVC的中断优先级大于当前执行的中断,这条指令就会立即触发SVC中断。
SVC指令使用一个8位立即数,这个参数不会直接影响SVC中断,而是执行SVC中断处理时,它会作为SVC函数的参数被提取出来。SVC一般可以作为系统服务的入口或者应用程序编程接口(API),这个参数可以用作指明所需的系统服务。
除了MSR指令,也可以使用CPS指令改变PRIMASK特殊寄存器的值。
2.5 休眠模式特性相关指令
通过执行WFI(等待中断)和WFE(等待事件)指令来进入休眠模式。
WFE同WFI类似,只是可以将它唤醒的事件不同。事件可以是中断、SEV指令的执行或者进入调试状态。
WFE也可以被外部事件输入信号唤醒,这通常用于多处理器环境中。
2.6 其它指令
Cortex-M0支持NOP指令,该指令可用作指令对齐或延时。
断点指令可以在调试中提供断点功能。调试器执行到断点时,处理器暂停处理,用户就可以使用调试器执行调试任务。
3. 指令集实例
3.1 函数调用和函数返回
当执行函数调用时(或子程序调用),需要保存返回地址,也就是调用指令后的下一条指令的地址。
执行完BL/BLX指令后,返回地址被保存在链接寄存器(LR/R14),这样在调用的函数执行完毕后还能进行函数返回。
嵌套函数调用和函数返回:
对函数中的多个寄存器进行压栈和出栈操作:
3.2 跳转表
使用C编程时,利用switch语句,可以根据输入值使程序跳转到多个可能的地址上。
使用汇编编程时,也可以实现类似操作:建立跳转目的地址表,根据输入计算表格的偏移并将其加载(LDR),然后使用BX执行跳转。
如上,R0中的可选输入为0-3,其对应程序跳转分支为Dest0 到 Dest3。