打印
[MM32软件]

Cortex-M0中断控制和系统控制(六)

[复制链接]
3190|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ARM处理器是基于精简指令计算机(RISC)原理设计的,指令集和相关译码机制较为简单,具有32位Arm指令集和16位Thumb指令集,Arm指令集效率高,但是代码密度低,而Thumb指令集具有更好的代码密度,却仍然保持Arm的大多数性能上的优势,它是Arm指令集的子集。所有Arm指令都是可以有条件执行的,而Thumb指令仅有一条指令具备条件执行功能。Arm程序和Thumb程序可相互调用,相互之间的状态切换开销几乎为零。
Cortex-M0处理器基于ARMv6-M架构,是一款功耗和性能较为均衡的处理器。Cortex-M0只支持56条指令的小指令集,其中大部分指令是16位指令。

Arm Cortex-M 指令集对比:






使用特权

评论回复
沙发
两只袜子|  楼主 | 2021-9-7 11:51 | 只看该作者
01指令集
1.1   在处理器内移动数据
MOV  <Rd>, <Rm> ;Rm and Rn can be high or low registers.
MOVS <Rd>, <Rm>
MOVS <Rd>, #immed8 ;8位立即数值

MRS  <Rd>, <SpecialReg>
MSR  <SpecialReg>, <Rd>1.2   存储器访问确保访问的内存地址是对齐的,这一点很重要。在ARMv6-M架构(包括Cortex-M0和Cortex-M0处理器)上不支持非对齐传输。任何未对齐内存访问的尝试都会导致HardFault异常。LDR  <Rt>,[<Rn>, <Rm>]    ; Rt = memory[Rn + Rm]
STR  <Rt>,[<Rn>, <Rm>]    ; memory[Rn + Rm] = Rt
LDRH <Rt>,[<Rn>, <Rm>]    ; Rt = memory[Rn + Rm]
STRH <Rt>,[<Rn>, <Rm>]    ; memory[Rn + Rm] = Rt
LDRB <Rt>,[<Rn>, <Rm>]    ; Rt = memory[Rn + Rm]
STRB <Rt>,[<Rn>, <Rm>]    ; memory[Rn + Rm] = Rt

LDRSH <Rt>,[<Rn>, <Rm>]   ; Rt = SignExtend(memory[Rn + Rm])
LDRSB <Rt>,[<Rn>, <Rm>]   ; Rt = SignExtend(memory[Rn + Rm])

LDR  <Rt>,[<Rn>, #immed5] ; Rt = memory[Rn + ZeroExtend (#immed5<<2)]
STR  <Rt>,[<Rn>, #immed5] ; memory[Rn + ZeroExtend(#immed5<<2)] = Rt
LDRH <Rt>,[<Rn>, #immed5] ; Rt = memory[Rn + ZeroExtend (#immed5<<1)]
STRH <Rt>,[<Rn>, #immed5] ; memory[Rn + ZeroExtend(#immed5<<1)] = Rt
LDRB <Rt>,[<Rn>, #immed5] ; Rt = memory[Rn + ZeroExtend (#immed5)]
STRB <Rt>,[<Rn>, #immed5] ; memory[Rn + ZeroExtend(#immed5)] = Rt

LDR  <Rt>,[SP, #immed8]   ; Rt = memory[SP + ZeroExtend(#immed8<<2)]
STR  <Rt>,[SP, #immed8]   ; memory[SP + ZeroExtend(#immed8<<2)] = Rt

LDR  <Rt>,[PC, #immed8]   ; Rt =memory[WordAligned(PC+4)+ZeroExtend(#immed8<<2)]
LDR  <Rd>, =immed32       ; pseudo instruction translated to LDR <Rt>,[PC, #immed8]
LDR  <Rd>, label          ; pseudo instruction translated to LDR <Rt>,[PC, #immed8]

LDM <Rn>,{<Ra>, <Rb>,..} ; Load Multiple
// Ra = memory[Rn]
// Rb = memory[Rn + 4],
// ...

LDMIA <Rn>!, {<Ra>, <Rb>,..} ; Load Multiple Increment After
LDMFD <Rn>!, {<Ra>, <Rb>,..}
// Ra = memory[Rn],
// Rb = memory[Rn + 4],
// ...
// and then update Rn to last read address plus 4.

STMIA <Rn>!, {<Ra>, <Rb>,..} ; Store Multiple Increment After
STMEA <Rn>!, {<Ra>, <Rb>,..}
// memory[Rn] = Ra,
// memory[Rn + 4] = Rb,
// ...
// and then update Rn to last store address plus 4.1.3   栈空间访问PUSH {<Ra>, <Rb>, ..}
PUSH {<Ra>, <Rb>, .., LR}
POP  {<Ra>, <Rb>, ..}
POP  {<Ra>, <Rb>, .., PC}1.4   算数运算ADD  <Rd>, <Rm>          ; Rd = Rd + Rm. Rd, Rm can be high or low registers.

ADDS <Rd>, <Rn>, <Rm>    ; Rd = Rn + Rm
SUBS <Rd>, <Rn>, <Rm>    ; Rd = Rn – Rm
ADDS <Rd>, <Rn>, #immed3 ; Rd = Rn + ZeroExtend(#immed3)
SUBS <Rd>, <Rn>, #immed3 ; Rd = Rn – ZeroExtend(#immed3)
ADDS <Rd>, #immed8       ; Rd = Rd + ZeroExtend(#immed8)
SUBS <Rd>, #immed8       ; Rd = Rd – ZeroExtend(#immed8)

ADCS <Rd>, <Rd>, <Rm>    ; Rd = Rd + Rm + Carry
SBCS <Rd>, <Rd>, <Rm>    ; Rd = Rd – Rm – Borrow

ADD  SP, SP, #immed7     ; SP = SP + ZeroExtend(#immed7<<2)
SUB  SP, SP, #immed7     ; SP = SP – ZeroExtend(#immed7<<2)
ADD  SP, <Rm>            ; SP = SP + Rm. Rm can be high or low register.

ADD  <Rd>, SP, <Rd>      ; Rd = Rd + SP. Rd can be high or low register.
ADD  <Rd>, SP, #immed8   ; Rd = SP + ZeroExtend(#immed8<<2)

ADD  <Rd>, PC, #immed8   ; Rd = (PC[31:2]<<2) + ZeroExtend(#immed8<<2)
ADR  <Rd>, <label>       ; pseudo instruction translated to ADD <Rd>, PC, #immed8

RSBS <Rd>, <Rn>,#0       ; Rd = 0 – Rm, Reverse Subtract (negative)

MULS <Rd>, <Rm>, <Rd>    ; Rd = Rd * Rm

CMP <Rn>, #immed8        ; Rd – ZeroExtended(#immed8)
CMP <Rn>, <Rm>           ; Rn – Rm
CMN <Rn>, <Rm>           ; Rn – NEG(Rm)1.5   逻辑运算ANDS <Rd>, <Rd>, <Rm> ; Rd = AND(Rd, Rm)
ORRS <Rd>, <Rd>, <Rm> ; Rd = OR(Rd, Rm)
EORS <Rd>, <Rd>, <Rm> ; Rd = XOR(Rd, Rm)
BICS <Rd>, <Rd>, <Rm> ; Rd = AND(Rd, NOT(Rm))
MVNS <Rd>, <Rm>       ; Rd = NOT(Rm)
TST  <Rn>, <Rm>       ; AND(Rn, Rm)1.6   移位和循环操作ASRS <Rd>, <Rm>, #immed5 ; Rd = Rm>>immed5
LSLS <Rd>, <Rm>, #immed5 ; Rd = Rm<<#immed5
LSRS <Rd>, <Rm>, #immed5 ; Rd = Rm>>#immed5
ASRS <Rd>, <Rd>, <Rm>    ; Rd = Rd>>Rm
LSLS <Rd>, <Rd>, <Rm>    ; Rd = Rd<<Rm
LSRS <Rd>, <Rd>, <Rm>    ; Rd = Rd>>Rm
RORS <Rd>, <Rd>, <Rm>    ; Rd = Rd rotate right by Rm bits
// Rotate_Left(Data, offset) = Rotate_Right(Data, (32-offset))1.7   展开和顺序反转操作这些反向指令通常用于在小端和之间转换数据大整数。REV <Rd>, <Rm> ; Byte-Reverse Word
// Rd = {Rm[7:0], Rm[15:8], Rm[23:16], Rm[31:24]}

REV16 <Rd>, <Rm> ; Byte-Reverse Packed Half Word
// Rd = {Rm[23:16], Rm[31:24], Rm[7:0] , Rm[15:8]}

REVSH <Rd>, <Rm> ; Byte-Reverse Signed Half Word
// Rd = SignExtend({Rm[7:0] , Rm[15:8]})1.8   扩展操作它们通常用于数据类型转换。SXTB <Rd>, <Rm> ; Signed Extended Byte
// Rd = SignExtend(Rm[7:0])

SXTH <Rd>, <Rm> ; Signed Extended Half Word
// Rd = SignExtend(Rm[15:0])

UXTB <Rd>, <Rm> ; Unsigned Extended Byte
// Rd = ZeroExtend(Rm[7:0])

UXTH <Rd>, <Rm> ; Unsigned Extended Half Word
// Rd = ZeroExtend(Rm[15:0])1.9   程序流控制B <label>       ; Branch, Branch range is ±2046 bytes of current PC
B<cond> <label> ; Conditional Branch, Branch range is ±254 bytes of current PC
BL <label>      ; Branch and Link, Branch range is ±16 MB of current PC
BX <Rm>         ; Branch and Exchange
BLX <Rm>        ; Branch and Link with Exchange

使用特权

评论回复
板凳
两只袜子|  楼主 | 2021-9-7 11:52 | 只看该作者
条件转移指令B
1.10   内存屏障指令
在Cortex-M0和Cortex-M0处理器上支持内存屏障指令,从而在Cortex-M处理器和其他ARM处理器家族中提供更好的兼容性。//数据内存屏障,确保所有内存访问都完成
//在新的内存访问被提交之前。

DMB
//数据同步屏障,确保所有的内存访问都完成
//在执行下一条指令之前。

DSB

//指令同步障碍,刷新管道和
//确保之前所有的指令都已完成
//在执行新指令之前。

Isb1.11   异常相关指令SVC <immed8> ; Supervisor call
CPSIE I      ; Enable Interrupt (Clearing PRIMASK)
CPSID I      ; Disable Interrupt (Setting PRIMASK)1.12   睡眠模式功能相关说明//等待中断,停止程序执行,直到一个中断到达,
//如果处理器进入调试状态。

WFI

//等待事件,如果设置了内部事件寄存器,则清除
//内部事件注册和继续执行。
//停止程序执行,直到事件(如中断)到达
//如果处理器进入调试状态。

WFE

//发送事件,设置本地事件寄存器并发送一个事件脉冲
//多处理器系统中的其他微处理器。

SEV1.13   其他说明NOP           ; No Operation
BKPT <immed8> ; Break point
YIELD         ; Execute as NOP on the Cortex-M0 processor02指令说明2.1   可访问high registers的指令绝大部分指令只能访问low registers,也就是只能访问R0~R7寄存器。可以访问high registers的指令只有两条,这两条指令都不更新APSR,指令没有S后缀。MOV  <Rd>, <Rm> ; Rm and Rn can be high or low registers.
ADD  <Rd>, <Rm> ; Rd = Rd + Rm. Rd, Rm can be high or low registers.

其它两条和SP加法有关的可以访问high registers的指令其本质是ADD指令。ADD  SP, <Rm>        
ADD  <Rd>, SP, <Rd> 2.2   分配临时变量的指令函数内的临时变量分配到堆栈,进入函数给临时变量分配空间时使用SUB指令。SUB  SP, SP, #immed7     ; SP = SP – ZeroExtend(#immed7<<2)

退出函数释放临时变量空间时使用ADD指令。ADD  SP, SP, #immed7     ; SP = SP + ZeroExtend(#immed7<<2)

上面两条指令的立即数只有7位,最多可以增减SP指针127个字空间,如果超过127个字,使用这条指令:ADD  SP, <Rm>            ; SP = SP + Rm. Rm can be high or low register.

只有ADD指令,没有SUB指令,如果需要SUB,那么给Rm赋值负数即可。
2.3   取临时变量地址的指令
在堆栈分配了临时变量空间后,总要取得临时变量的地址才能做进一步的操作。ADD  <Rd>, SP, #immed8   ; Rd = SP + ZeroExtend(#immed8<<2)

立即数不够,可以用寄存器。ADD  <Rd>, SP, <Rd>      ; Rd = Rd + SP. Rd can be highor low register.2.4   RSBS指令RSBS <Rd>, <Rn>, #0       ; Rd = 0 – Rm, Reverse Subtract (negative)

这是倒过来的减法,常量减去寄存器值,而且常量只能是0。所以这条指令实质上就是一条取负数指令。

Rd = 0 - Rm
等价于:Rd = -Rm
Rd 寄存器值等于负的 Rm 寄存器值。

使用特权

评论回复
地板
koala889| | 2021-9-18 16:34 | 只看该作者
额,不懂啊,这是什么

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2055

主题

7458

帖子

10

粉丝