cortex-M3内核简单分析
1、cortex - M3内核:只是arm公司提供的一个内核
基于cortex - M3的MCU:包括内核+内存+外设等一些其他的器件。
2、cortex -M3架构的特点:
(1)处理器内核,数据路径,寄存器,存储器接口都是32位的。
(2)采用哈佛结构,数据总线和指令总线是独立的,取指令和读数据可以同时进行。
(3)支持大段模式和小端模式
3、寄存器R0-R12 通用寄存器 一般16位的thumb指令能访问R0-R7 ;
4、异常的概念:
凡是打断程序执行顺的事件都被称为异常。
5、CM3支持两种操作模式:handler mode 和 thread mode
同时还是支持两级特权操作: 特权级和用户级
从用户级切换到特权级唯一的途径就是异常。
6、特权级线程模式和用户级线程模式都可以触发异常到特权级handler mode,并且会异常返回。
复位进入特权级线程模式,特权级线程模式通过修改控制寄存器进入到用户级线程模式。
7、内建的嵌套中断控制器
*可嵌套中断支持
当异常发生时,硬件会自动比较异常的优先级是否比当前的优先级高,如果必当前的优先级高就会服务新来的中断,–立即强占
*向量中断支持
当中断响应后,CM3会自动定位到一张向量表,并且根据中断号从表中找出ISR的入口地址,跳转过去执行。(节省时间延迟时间缩短)
*动态优先级调整
软件运行期间可以更改中断的优先级,如果修改了当前的优先级,当前中断是不会自己打断自己的,从而没有重入风险。
*中断延迟大大缩短
*中断可屏蔽
可以任意屏蔽中断序号,也可以全部屏蔽。是为了让时间关键的任务能在死线到来之前完成,而不被干扰。
8、存储器映射
存储器大小是4G,分成6个区间,Cortex-M3内部拥有一个总线基础设施,在此基础上,甚至允许这些区间之间“越权使用”。
9、指令流水线
取指令(F)–解码(D)–执行(X)三级指令,
pc指向预取指令,pc地址与执行的地址相差8 (pc-8=x)
0x1000 mov (执行此处)
0x1004 sub (解码此处)
0x1008 mul (pc指向此时)
0x100c dev
当发生指令跳转时:
跳转到目的地后用LR记录返回地址,并且将当前的D、X,清空,如果预取指令再一周期将LR的值减去4
10、复位发生后指向默认的MSP,而PC的值是4,
11、UAL(统一汇编语言),但是仍然允许使用传统的 Thumb 语法。不过有一项必须注意:如果
使用传统的 Thumb 语法,有些指令会默认地更新 APSR,即使你没有加上 S 后缀。如果使用
UAL 语法,则必须指定 S 后缀才会更新。
12、在UAL 下,你可以让汇编器决定用哪个,也可以手工指定是用 16 位的还是 32 位的:
ADDS R0, #1 ;汇编器将为了节省空间而使用 16 位指令
ADDS.N R0, #1 ;指定使用 16 位指令(N=Narrow)
ADDS.W R0, #1 ;指定使用 32 位指令(W=Wide)
13、指令集
名字 功能
ADC 带进位加法
ADD 加法
AND 按位与(原文为逻辑与,有误——译注)。这里的按位与和 C 的”&”功能相同
ASR 算术右移
BIC 按位清 0(把一个数跟另一个无符号数的反码按位与)
CMN 负向比较(把一个数跟另一个数据的二进制补码相比较)
CMP 比较(比较两个数并且更新标志)
CPY 把一个寄存器的值拷贝到另一个寄存器中
EOR 近位异或
LSL 逻辑左移(如无其它说明,所有移位操作都可以一次移动多格——译注)
LSR 逻辑右移
MOV 寄存器加载数据,既能用于寄存器间的传输,也能用于加载立即数
MUL 乘法
MVN 加载一个数的 NOT 值(取到逻辑反的值)
NEG 取二进制补码
ORR 按位或(原文为逻辑或,有误——译注)
ROR 圆圈右移
SBC 带借位的减法
SUB 减法
TST 测试(执行按位与操作,并且根据结果更新 Z)
REV 在一个 32 位寄存器中反转字节序
REVH 把一个 32 位寄存器分成两个 16 位数,在每个 16 位数中反转字节序
REVSH 把一个 32 位寄存器的低 16 位半字进行字节反转,然后带符号扩展到 32 位
SXTB 带符号扩展一个字节到 32 位
SXTH 带符号扩展一个半字到 32 位
UXTB 无符号扩展一个字节到 32 位
UXTH 无符号扩展一个半字到 32 位
表 4.3 16 位转移指令
名字 功能
B 无条件转移
B 条件转移
BL 转移并连接。用于呼叫一个子程序,返回地址被存储在 LR 中
BLX #im 使用立即数的 BLX 不要在 CM3 中使用
CBZ 比较,如果结果为 0 就转移(只能跳到后面的指令——译注)
CBNZ 比较,如果结果非 0 就转移(只能跳到后面的指令——译注)
IT If‐Then
55Cortex‐M3 权威指南 初稿 第 4 章
表 4.4 16 位存储器数据传送指令
名字 功能
LDR 从存储器中加载字到一个寄存器中
LDRH 从存储器中加载半字到一个寄存器中
LDRB 从存储器中加载字节到一个寄存器中
LDRSH 从存储器中加载半字,再经过带符号扩展后存储一个寄存器中
LDRSB 从存储器中加载字节,再经过带符号扩展后存储一个寄存器中
STR 把一个寄存器按字存储到存储器中
STRH 把一个寄存器存器的低半字存储到存储器中
STRB 把一个寄存器的低字节存储到存储器中
LDMIA 加载多个字,并且在加载后自增基址寄存器
STMIA 加载多个字,并且在加载后自增基址寄存器
PUSH 压入多个寄存器到栈中
POP 从栈中弹出多个值到寄存器中
16 数据传送指令没有任何新内容,因为它们是 Thumb 指令,在 v4T 时就已经定格了——译注
表 4.5 其它 16 位指令
名字 功能
SVC 系统服务调用
BKPT 断点指令。如果调试被使能,则进入调试状态(停机)。或者如果调试监视器异常被
使能,则调用一个调试异常,否则调用一个 fault 异常
NOP 无操作
CPSIE 使能 PRIMASK(CPSIE i)/ FAULTMASK(CPSIE f)——清 0 相应的位
CPSID 除能 PRIMASK(CPSID i)/ FAULTMASK(CPSID f)——置位相应的位
表 4.6 32 位数据操作指令
名字 功能
ADC 带进位加法
ADD 加法
ADDW 宽加法(可以加 12 位立即数)
AND 按位与(原文是逻辑与,有误——译注)
ASR 算术右移
BIC 位清零(把一个数按位取反后,与另一个数逻辑与)
BFC 位段清零
BFI 位段插入
CMN 负向比较(把一个数和另一个数的二进制补码比较,并更新标志位)
CMP 比较两个数并更新标志位
56Cortex‐M3 权威指南 初稿 第 4 章
CLZ 计算前导零的数目
EOR 按位异或
LSL 逻辑左移
LSR 逻辑右移
MLA 乘加
MLS 乘减
MOVW 把 16 位立即数放到寄存器的底 16 位, 高 16 位清 0
MOV 加载 16 位立即数到寄存器(其实汇编器会产生 MOVW——译注)
MOVT 把 16 位立即数放到寄存器的高 16 位, 低 16 位不影响
MVN 移动一个数的补码
MUL 乘法
ORR 按位或(原文为逻辑或,有误——译注)
ORN 把源操作数按位取反后,再执行按位或(原文为逻辑或,有误——译注)
RBIT 位反转(把一个 32 位整数先用 2 进制表达,再旋转 180 度——译注)
REV 对一个 32 位整数做按字节反转
REVH/
REV16
对一个 32 位整数的高低半字都执行字节反转
REVSH 对一个 32 位整数的低半字执行字节反转,再带符号扩展成 32 位数
ROR 圆圈右移
RRX 带进位的逻辑右移一格(最高位用 C 填充,且不影响 C 的值——译注)
SFBX 从一个 32 位整数中提取任意的位段,并且带符号扩展成 32 位整数
SDIV 带符号除法
SMLAL 带符号长乘加(两个带符号的 32 位整数相乘得到 64 位的带符号积,再把积加到另一
个带符号 64 位整数中)
SMULL 带符号长乘法(两个带符号的 32 位整数相乘得到 64 位的带符号积)
SSAT 带符号的饱和运算
SBC 带借位的减法
SUB 减法
SUBW 宽减法,可以减 12 位立即数
SXTB 字节带符号扩展到 32 位数
TEQ 测试是否相等(对两个数执行异或,更新标志但不存储结果)
TST 测试(对两个数执行按位与,更新 Z 标志但不存储结果)
UBFX 无符号位段提取
UDIV 无符号除法
UMLAL 无符号长乘加(两个无符号的 32 位整数相乘得到 64 位的无符号积,再把积加到另一
个无符号 64 位整数中)
UMULL 无符号长乘法(两个无符号的 32 位整数相乘得到 64 位的无符号积)
USAT 无符号饱和操作(但是源操作数是带符号的——译注)
UXTB 字节被无符号扩展到 32 位(高 24 位清 0——译注)
UXTH 半字被无符号扩展到 32 位(高 16 位清 0——译注)
57Cortex‐M3 权威指南 初稿 第 4 章
表 4.7 32 位存储器数据传送指令
名字 功能
LDR 加载字到寄存器
LDRB 加载字节到寄存器
LDRH 加载半字到寄存器
LDRSH 加载半字到寄存器,再带符号扩展到 32 位
LDM 从一片连续的地址空间中加载多个字到若干寄存器
LDRD 从连续的地址空间加载双字(64 位整数)到 2 个寄存器
STR 存储寄存器中的字
STRB 存储寄存器中的低字节
STRH 存储寄存器中的低半字
STM 存储若干寄存器中的字到一片连续的地址空间中
STRD 存储 2 个寄存器组成的双字到连续的地址空间中
PUSH 把若干寄存器的值压入堆栈中
POP 从堆栈中弹出若干的寄存器的值
表 4.8 32 位转移指令
名字 功能
B 无条件转移
BL 转移并连接(呼叫子程序)
TBB 以字节为单位的查表转移。从一个字节数组中选一个 8 位前向跳转地址并转移
TBH 以半字为单位的查表转移。从一个半字数组中选一个 16 位前向跳转的地址并转移
表 4.9 其它 32 位指令
LDREX 加载字到寄存器,并且在内核中标明一段地址进入了互斥访问状态
LDREXH 加载半字到寄存器,并且在内核中标明一段地址进入了互斥访问状态
LDREXB 加载字节到寄存器,并且在内核中标明一段地址进入了互斥访问状态
STREX 检查将要写入的地址是否已进入了互斥访问状态,如果是则存储寄存器的字
STREXH 检查将要写入的地址是否已进入了互斥访问状态,如果是则存储寄存器的半字
STREXB 检查将要写入的地址是否已进入了互斥访问状态,如果是则存储寄存器的字节
CLREX 在本地的处理上清除互斥访问状态的标记(先前由 LDREX/LDREXH/LDREXB 做的标记)
MRS 加载特殊功能寄存器的值到通用寄存器
MSR 存储通用寄存器的值到特殊功能寄存器
NOP 无操作
SEV 发送事件
WFE 休眠并且在发生事件时被唤醒
WFI 休眠并且在发生中断时被唤醒
ISB 指令同步隔离(与流水线和 MPU 等有关——译注)
DSB 数据同步隔离(与流水线、 MPU 和 cache 等有关——译注)
58Cortex‐M3 权威指南 初稿 第 4 章
DMB 数据存储隔离(与流水线、 MPU 和 cache 等有关——译注)
14、当使用16位指令时,会自动更新APSR标志位,在使用了“.w”指定的32位的指令后,就可以通过手动的增加S进行标志位的更新。
15、寄存器立即数的种类大约有四种
使用伪指令 LDR Rn,=const
系统会自己根据const,自动选择赋值方法。
16、 Bl (保存返回地址)
BX rd(寄存器) ;转移到有寄存器rd给出的地址
在 BX中,reg的最低位指示出在转移后,将进入的状态是 ARM(LSB=0)还是 Thumb(LSB=1)。
既然 CM3 只在 Thumb 中运行,就必须保证 reg 的 LSB=1
loop
add r1,r1,#1
add r2,r2,r1
subs r3,r1,#100
beq step
b loop
step
17、对特殊寄存器的操作含义
MRS Move to Register from State register
MSR Move from State registerto Register
18、对寄存器进行串操作
STMIA.W R8!, {r0-R3} ; R8 值变为 0x8010,每存一次曾一次,先存储后自增
STMDB.W R8, {R0-R3} ; R8 值的“一个内部复本”先自减后存储,但是 R8 的值不变
19、预索引和后索引
ldr r2, [r0, r3]! ;错误,寄存器提供偏移量时不支持预索引
ldr r2, [r0], r3 ;错误,寄存器提供偏移量时不支持后索引
20、在 CM3 中,下列指令可以更新 PSR 中的标志:
16 位算术逻辑指令
32 位带 S 后缀的算术逻辑指令
比较指令(如, CMP/CMN)和测试指令(如 TST/TEQ)
直接写 PSR/APSR (MSR 指令)
21、大小端转换
例如,记 R0=0x12345678,在执行下列两条指定后:
REV R1, R0
REVH R2, R0
REV16 R3, R0
则 R1=0x78563412, R2=0x12347856, R3=0x34127856。
比特转换(翻转180°)
例如,记 R1=0xB4E10C23(二进制数值为 1011,0100,1110,0001,0000,1100,0010,0011),
RBIT.W R0, R1
执行后,则 R0=0xC430872D(二进制数值为 1100,0100,0011,0000,1000,0111,0010,1101)
22、数据段NOINIT
在数据段只是保留了内存单元,并没有将各个初始值写入内存单元,或是初始化为0
————————————————
版权声明:本文为CSDN博主「Castle_in_sky」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_37689106/article/details/83016963