条件代码
条件代码
每个指令的顶端部分是一个条件代码,所以可以有条件的运行每个单一的 ARM 指令。
条件
指令位图 编号 条件代码 所须标志:
0000xxxx xxxxxxxx xxxxxxxx xxxxxxxx 0 EQ(等于,Equal) Z
0001xxxx xxxxxxxx xxxxxxxx xxxxxxxx 1 NE(不等于,Not Equal) ~Z
0010xxxx xxxxxxxx xxxxxxxx xxxxxxxx 2 CS(进位设置,Carry Set) C
0011xxxx xxxxxxxx xxxxxxxx xxxxxxxx 3 CC(进位清除,Carry Clear) ~C
0100xxxx xxxxxxxx xxxxxxxx xxxxxxxx 4 MI(负号,MInus) N
0101xxxx xxxxxxxx xxxxxxxx xxxxxxxx 5 PL(正号,PLus) ~N
0110xxxx xxxxxxxx xxxxxxxx xxxxxxxx 6 VS(溢出设置,oVerflow Set) V
0111xxxx xxxxxxxx xxxxxxxx xxxxxxxx 7 VC(溢出清除,oVerflow Clear) ~V
1000xxxx xxxxxxxx xxxxxxxx xxxxxxxx 8 HI(高于,HIgher) C and ~Z
1001xxxx xxxxxxxx xxxxxxxx xxxxxxxx 9 LS(低于或同于,Lower or Same) ~C and Z
1010xxxx xxxxxxxx xxxxxxxx xxxxxxxx A GE(大于等于,Greater or equal)N = V
1011xxxx xxxxxxxx xxxxxxxx xxxxxxxx B LT(小于,Less Than) N = ~V
1100xxxx xxxxxxxx xxxxxxxx xxxxxxxx C GT(大于,Greater Than) (N = V) and ~Z
1101xxxx xxxxxxxx xxxxxxxx xxxxxxxx D LE(小于等于,Less or equal) (N = ~V) or Z
1110xxxx xxxxxxxx xxxxxxxx xxxxxxxx E AL(总是,Always) 永真
1111xxxx xxxxxxxx xxxxxxxx xxxxxxxx F NV(从不,Never) 永假
在多数汇编器中,插入条件代码到紧随在助记符根代码(stub)的后面;省略条件代码缺省为使用 AL。
在一些汇编器中把 HS (高于或同于) 和 LO (低于) 分别用做 CS 和 CC 的同义词。
条件 GT、GE、LT、LE 被成为有符号比较,而 HS、HI、LS、LO 被称为无符号比较。
把一个条件代码与 1 进行异或得到相反的条件的代码。
NB: ARM 废弃使用 NV 条件代码 - 假定你使用 MOV R0,R0 作为一个空指令而不是以前推荐的 MOVNV R0,R0 。将来的处理器可能重新使用 NV 条件来做其他事情。
所须条件为假的指令执行 1S 周期,使一个指令有条件执行不招致时间处罚。
数据处理指令
数据处理指令
xxxx000a aaaSnnnn ddddcccc ctttmmmm 寄存器形式
xxxx001a aaaSnnnn ddddrrrr bbbbbbbb 立即数形式
典型的汇编语法:
MOV Rd, #0
ADDEQS Rd, Rn, Rm, ASL Rc
ANDEQ Rd, Rn, Rm
TEQP Pn, #&80000000
CMP Rn, Rm
在操作 a 下,组合 Rn 的内容和 Op2,放置结果到 Rd 中。
如果使用寄存器形式,则 Op2 被设置为依据下面描述的 t 来移位的 Rm 的内容。如果使用立即数形式,则 Op2 = #b, ROR #2r。
t 汇编器 解释
000 LSL #c 逻辑左移
001 LSL Rc 逻辑左移
010 LSR #c for c != 0 逻辑右移
LSR #32 for c = 0
011 LSR Rc 逻辑右移
100 ASR #c for c != 0 算术右移
ASR #32 for c = 0
101 ASR Rc 算术右移
110 ROR #c for c != 0 循环右移
RRX for c = 0 带扩展的循环右移一位
111 ROR Rc 循环右移
在寄存器形式中,用位 8-11 表示 Rc;如果使用 Rc 则位 7 必须清除。(如果你编码为 1,你将得到一个乘法、SWP 或未分配的指令而不是一个数据处理指令。)
还有,只使用了 Rc 的底端字节 - 如果 Rc = 256, 则移位将是零。
“MOV[S] Ra,Rb,RLX” 可以通过 ADC[S] Ra,Rb,Rb 来完成,这里的 RLX 意思是带扩展的循环左移一位。
多数汇编器允许使用 ASL 作为 LSL 的同义词。因为对算术左移是什么有不同的意见,最好使用术语 LSL。
通过在 MOV、MVN 或逻辑指令中设置 S 位,(在寄存器或立即数形式中)把进位标志设置为最后移出的那一位。
如果不做移位,则不影响进位标志。
如果立即数有可选择的多个形式(例如,#1 可以表示为 1 ROR #0、4 ROR #2、16 ROR #4 或 64 ROR #6),则汇编器希望使用涉及零移位的那个形式,如果可获得的话。所以,如果 0 <= const <= 255,则 MOVS Rn,#const 将保持进位标志不受影响,否则将改变它。
aaaa 汇编器 意思 P-Code
0000 AND 逻辑与 Rd = Rn AND Op2
0001 EOR 逻辑异或 Rd = Rn EOR Op2
0010 SUB 减法 Rd = Rn - Op2
0011 RSB 反向减法 Rd = Op2 - Rn
0100 ADD 加法 Rd = Rn + Op2
0101 ADC 带进位的加法 Rd = Rn + Op2 + C
0110 SBC 带借位的减法 Rd = Rn - Op2 - (1-C)
0111 RSC 带借位的反向减法 Rd = Op2 - Rn - (1-C)
1000 TST 测试位 Rn AND Op2
1001 TEQ 测试等同 Rn EOR Op2
1010 CMP 比较 Rn - Op2
1011 CMN 比较取负 Rn + Op2
1100 ORR 逻辑或 Rd = Rn OR Op2
1101 MOV 传送值 Rd = Op2
1110 BIC 位清除 Rd = Rn AND NOT Op2
1111 MVN 传送取非 Rd = NOT Op2
注意 MVN 和 CMN 不是象表面上的那种关系;MVN 使用直接的逐位(bitwise)非操作,把 Rn 设置为 Op2 对 1 的补码(反码)。CMN 把 Rn 与 Op2 对 2 的补码进行比较。 这些指令可归入 4 个子集:
MOV, MVN Rn 被忽略,并且应当是 0000。如果设置了 S 位,则在结果上设置 N 和 Z 标志。并且如果使用了移位器,则 C 标志被设置为被移出的最后一位。不影响 V 标志。 CMN, CMP, TEQ, TST Rd 不被指令所设置,并且应当是 0000。必须设置 S 位(多数汇编器会自动完成;如果没有设置它,则这个指令将是 MRS、MSR、或一个未分配的指令。) 算术操作(CMN, CMP)在结果上设置 N 和 Z 标志,从 ALU 得到 C 和 V 标志。
逻辑操作(TEQ, TST)在结果上设置 N 和 Z 标志,如果使用了移位器则从它得到 C 标志(在这种情况下它变成被移出的最后一位),不影响 V 标志。
有一个特殊情况(对于 ARMs >= 6,只针对 26 位模式),dddd 字段是 1111 导致用结果的相应的位设置标志(在用户模式下),或整个 26 位 PSR (在特权模式下)。这由给指令的 P 后缀来指示 - CMNP、 CMPP、TEQP、TSTP。常用 TEQP PC,#(新模式编号) 来改变模式。在 32 位模式,应当使用 MSR 来替代(因为 TEQP 等不再工作)。
ADC, ADD, RSB, RSC, SBC, SUB 如果设置了 S 位,则在结果上设置 N 和 Z 标志,从 ALU 的得到 C 和 V 标志。 AND, BIC, EOR, ORR 如果设置了 S 位,则在结果上设置 N 和 Z 标志,如果使用了移位器则从它得到 C 标志(在这种情况下它变成被移出的最后一位),不影响 V 标志。 可以使用 ADD 和 SUB 以与位置无关的方式使寄存器指向数据,例如 ADD R0,PC,#24。这很有用,一些汇编器有一个叫做 ADR 的特殊宏指令(directive),它自动生成恰当的 ADD 或 SUB 指令。(ADR R0, fred 典型的把 fred 的地址放置到 R0 中,假定 fred 在范围内)。
在 26-bit 模式下,在 R15 是使用的寄存器之一的时候发生一种特殊情况:
如果 Rn = R15 则使用的 R15 值屏蔽掉了所有 PSR 位。 如果 Op2 涉及 R15,则使用所有的 32 位。 在 32-bit 模式下,使用 R15 的所有的位。
在 26-bit 模式下,如果 Rd = R15 则:
如果未设置 S 位,则只设置 PC 的 24 位。 如果设置了 S 位,则覆写 PC 和 PSR 二者(除非在非用户模式下,否则不改变模式位、I 和 F 位。) 对于 32-bit 模式, 如果 Rd=15,则覆写 PC 的所有的位,不包括最低的那两个有效位,它们总是零。如果未设置 S 位,则只进行上面这些;如果设置了 S 位,把当前模式的 SPSR 复制到 CPSR 中。在 32-bit 用户模式下,你不应该执行把 PC 作为目的寄存器并设置了 S 位的指令,因为用户模式没有 SPSR。(顺便说一句,你这样做不会打断处理器 - 这样做的结果只是未定义而已,且在不同的处理器上可能不同。)
执行这些指令使用下列数目的周期: 1S + (1S 如果使用了寄存器控制的移位) + (1S + 1N 如果改变了 PC) |