在嵌入式系统开发中,条件执行是提升代码效率的关键技术。ARM架构通过状态寄存器(APSR)的四个标志位实现精细化的指令流控制:
ARM指令的cond字段支持16种条件组合(如EQ、NE、GT等),典型条件判断逻辑如下表所示:
| 条件码 | 助记符 | 生效条件 | 典型应用场景 |
|---|---|---|---|
| 0000 | EQ | Z=1 | 相等比较 |
| 0001 | NE | Z=0 | 不等比较 |
| 1010 | GE | N==V | 有符号数大于等于 |
| 1011 | LT | N!=V | 有符号数小于 |
| 1100 | GT | Z=0且N==V | 有符号数大于 |
| 1101 | LE | Z=1或N!=V | 有符号数小于等于 |
实战经验:在循环控制中,使用
BNE替代BEQ+B的组合可节省1条指令,这在密集循环中能显著提升性能。
Thumb-2指令集通过三种机制实现条件执行:
条件分支指令:
B<cond>,跳转范围-256~+254字节CBZ/CBNZ指令:
assembly复制CBZ R0, target ; R0为零时跳转
CBNZ R1, loop ; R1非零时继续循环
这种零值判断指令特别适合循环控制,编码效率比传统条件分支更高。
IT指令块:
assembly复制ITETE NE ; 条件为NE时执行1、3条,否则执行2、4条
ADDNE R0, R1 ; 第1条
ADDEQ R0, R2 ; 第2条
SUBNE R3, #1 ; 第3条
SUBEQ R3, #2 ; 第4条
IT指令最多可控制4条后续指令的条件执行,但需注意:
ARM提供丰富的运算指令,其通用格式为:
<opcode>{<cond>}{S} <Rd>, <Rn>, <operand2>
其中operand2可以是:
#0xFF或#0xF00(12位编码)RmRm, LSL #2典型指令示例:
assembly复制ADD R0, R1, R2, LSR #3 ; R0 = R1 + (R2 >> 3)
RSB R3, R4, #0x100 ; R3 = 0x100 - R4
ORR R5, R6, #0x3F ; R5 = R6 | 0x3F
性能提示:在Cortex-M系列中,使用
RSB实现取反比MVN更快,因为后者需要额外移位操作。
ARM支持五种移位方式:
| 操作码 | 描述 | 示例 |
|---|---|---|
| LSL | 逻辑左移 | MOV R0, R1, LSL #2 |
| LSR | 逻辑右移 | MOV R0, R1, LSR #3 |
| ASR | 算术右移(保留符号位) | MOV R0, R1, ASR #4 |
| ROR | 循环右移 | MOV R0, R1, ROR #5 |
| RRX | 带扩展的循环右移 | MOV R0, R1, RRX |
特殊案例:
assembly复制; 使用RRX实现32位累加器扩展为33位
ADDS R0, R1 ; 设置C标志
RRX R2, R2 ; 将C移入R2最高位
乘法指令分类:
assembly复制MUL R0, R1, R2 ; R0 = R1 × R2 (低32位)
assembly复制SMULL R0, R1, R2, R3 ; R1:R0 = R2 × R3 (64位)
assembly复制MLA R0, R1, R2, R3 ; R0 = R1×R2 + R3
除法注意事项:
SDIV/UDIV)饱和运算在数字信号处理中至关重要,防止数据溢出导致的失真:
assembly复制QADD R0, R1, R2 ; R0 = sat(R1 + R2)
USAT R3, #8, R4 ; 将R4饱和到8位无符号数
典型应用场景:
通过ADD8/SUB16等指令实现单指令多数据操作:
assembly复制SADD16 R0, R1, R2 ; 同时完成两个16位加法
UADD8 R3, R4, R5 ; 同时完成四个8位加法
性能对比:
| 操作类型 | 传统指令周期 | SIMD指令周期 | 加速比 |
|---|---|---|---|
| 4个8位加法 | 4 | 1 | 4x |
| 2个16位乘法 | 2 | 1 | 2x |
ARMv7引入的位域操作极大提升了嵌入式协议处理效率:
assembly复制; 从R1的bit[15:8]提取到R0的bit[7:0]
UBFX R0, R1, #8, #8
; 将R2的低4位插入R3的bit[20:17]
BFI R3, R2, #17, #4
在CAN总线数据处理中,这些指令可将传统移位-掩码操作从5-6条指令缩减为1条。
循环展开与条件执行:
assembly复制ITTTT EQ
STREQ R0, [R1], #4
STREQ R2, [R1], #4
STREQ R3, [R1], #4
STREQ R4, [R1], #4
这种组合比单独判断效率提升3倍以上。
条件数据预处理:
assembly复制CMP R0, #0
ITE NE
ADDNE R1, R2, #1
MOVEQ R1, #0
IT指令使用错误:
assembly复制IT EQ
ADDEQ R0, R1 ; 正确
ADDNE R2, R3 ; 错误!条件必须匹配IT
标志位污染:
assembly复制CMP R0, R1
; 此处插入非标志设置指令会导致条件判断失效
BEQ target
Thumb-2条件限制:
在电机控制算法中,合理使用条件执行可使FOC循环从56周期降至42周期,提升25%实时性。一个典型的PID控制器实现中,通过条件执行和饱和运算的组合,既能保证控制精度,又能防止积分饱和问题。