为什么下面编译:
ITE EQ
MRSEQ R0, MSP
MRSNE R0, PSP
但这不是:
ITT NE
MRSNE R0, PSP
MRSEQ R0, MSP
是否有可能,MRSNE R0,PSP和MRSEQ R0,MSP都执行(这是我的情况(?
这将编译:
ITT NE
MRSNE R0, PSP
MRSNE R0, MSP
它是 ARM 标准吗?
概述
但这不是:
ITT NE MRSNE R0, PSP MRSEQ R0, MSP
首先,您有一些概念问题。 ITT
到底是怎么回事? 首先是一些历史。 早期的ARM CPU不支持Thumb(16位(或Thumb2(混合16/32位(编码。 对于纯 ARM,很大一部分(4 个前导位(专用于条件执行。 拇指指令集不支持条件执行。 对于 Thumb2(你想要的 Cortex-M 部分(,条件执行有一个变化。 不是在每个指令中编译一个条件,而是有一个it
指令,它在条件寄存器中设置8位。
it
指令给出了与测试(EQ
、NE
、LO
等(的比较。 然后,它最多提供四个条件指令。 来自 Cortex-A 程序员手册,
文档
第 A.1.34 节
IT(If-then(最多有四个以下指令是条件的(称为IT
块(。条件可以都相同,或者有些条件可能是其他条件的逻辑反转。 IT
是处于 ARM 状态的伪指令。
语法:IT{x{y{z}}} {cond}
其中:cond 是一个条件代码。请参阅第 6.1.2 节,其中指定了 IT 块中第一条指令的条件。
x、y 和 z 指定IT
块中第二、第三和第四条指令的条件开关,例如 ITTET
。条件开关可以是:
- T(然后(,将条件 cond 应用于指令。
- E(Else(,它将 cond 的反条件应用于指令。
Thumb2 条件块的限制
为了同时支持 Thumb2 和 ARM 汇编程序,创建了一种称为统一汇编语言的新模式。参考: 统一语法
对于纯 ARM,IT
的计算结果为零。 指令与条件一起编码。对于 Thumb2,它会启动条件寄存器以设置条件位。 ARM汇编程序有三种模式; .arm
、.thumb
和.unified
。 还.code 32
和.code 16
。 根据使用的模式和特定的汇编程序(Gnu,ARM等(,您将收到不同的警告和/或错误。 但是,对于您的序列,此模式永远不会失败,
ITE NE ; first NE, 2nd !NE = EQ (Thumb2)
MRSNE R0, PSP ; first NE (ARM)
MRSEQ R0, MSP ; 2nd !NE = EQ (ARM)
MRS
指令是"IT 块"。 在您的情况下,您使用 thumb2 特殊寄存器,因此统一语法对手头的任务没有多大意义。 请参阅下面的注释。
了解一些规则来制作统一的IT
块。
IT
块不应设置条件代码。即,cmpne
指令。- 您不应分支到
IT
块。 - 我们总是从
IT
开始,所以IT
中的cond必须与第一条指令匹配。 - 以下指令必须匹配 cond(如果为"T"(或 !cond (如果为"E"。
- 您不应更改条件寄存器
PSR
、cpsr
等。 - 您只能混合相反的类型。 例如
movlo r1, #-1
moveq r1, #0
movhi r1, #1
可以在ARM中工作,但不能在Thumb2中工作。 在您的情况下,您违反了规则"4"并收到错误。 此外,ARM允许无条件指令与条件指令混合。 但一般来说,当 90-99% 的情况在编译代码中无条件执行时,拥有这些额外的操作码位是高昂的代价。
检查操作码
例:
.text
.syntax unified
ITE NE @ first NE, 2nd !NE = EQ (Thumb2)
movne R0, #1 @ first NE (ARM)
moveq R0, #2 @ 2nd !NE = EQ (ARM)
拆解的 ARM,
00000000 <.text>:
0: 13a00001 movne r0, #1
4: 03a00002 moveq r0, #2
拆解的拇指2,
00000000 <.text>:
0: bf14 ite ne
2: 2001 movne r0, #1
4: 2002 moveq r0, #2
对于 thumb2,这是没有ITE
指令的等效项,
00000000 <.text>:
0: 2001 movs r0, #1
2: 2002 movs r0, #2
即,设置条件代码的两个动作。 拆装器中的第二个数字当然是机器代码。 对于 thumb2 操作系统/调度程序,它将恢复条件寄存器,该寄存器恢复IT
状态,您可以进入IT
块的中间。 也可以手动执行此操作(但是,它可能高度特定于 CPU,并且据我所知没有记录(。
Thumb2 为 6 个字节,ARM 代码为 8 个字节,以实现等效功能。 如果条件块中包含"宽"(32 位(操作码,则 Thumb2 将需要更多的代码空间。
注意:对于改变PSR
的 Cortex-M 调度程序代码,需要使用分支。 这些寄存器控制IT
块执行。 不应修改IT
块中的PSR
。 这同样适用于任何上下文还原指令;我不是 100% 熟悉 Cortex-M 模式切换,它涉及更改活动PSR
。