在嵌入式系统开发中,逻辑运算和移位操作是最基础也是最核心的指令类型。Cortex-M3作为ARMv7-M架构的代表,其指令集针对嵌入式场景进行了精心优化。逻辑指令(AND/ORR/EOR等)和移位指令(ASR/LSL/LSR等)共同构成了数据处理的基础工具链,它们具有以下关键特性:
这些指令在底层开发中应用广泛:
c复制// 典型应用场景示例
#define GPIO_ODR (*(volatile uint32_t*)0x4001080C)
void set_pin(uint8_t pin) {
__asm volatile(
"ORR %[odr], %[mask] \n\t" // 置位指定引脚
: [odr] "+r" (GPIO_ODR)
: [mask] "r" (1 << pin)
);
}
Cortex-M3支持五种核心逻辑指令,其机器编码格式为:
code复制31-28 27-25 24-21 20 19-16 15-12 11-0
[cond] [001] [opcode] [S] [Rn] [Rd] [Operand2]
各指令功能对比如下:
| 指令 | 助记符 | 运算规则 | 典型应用 |
|---|---|---|---|
| 与 | AND | Rd = Rn & Operand2 | 位掩码清除 |
| 或 | ORR | Rd = Rn | Operand2 | 位设置 |
| 异或 | EOR | Rd = Rn ^ Operand2 | 位翻转 |
| 位清除 | BIC | Rd = Rn & ~Operand2 | 位清除 |
| 或非 | ORN | Rd = Rn | ~Operand2 | 复合操作 |
逻辑指令支持通过cond字段实现条件执行,例如:
assembly复制ANDNE R0, R1, #0xFF ; 仅当Z=0时执行
S后缀控制APSR标志位更新规则:
重要提示:在中断处理等关键路径代码中,合理使用S后缀可以避免额外的CMP指令,但要注意标志位的副作用。
外设寄存器操作
assembly复制; 设置USART1的TE位(bit3)
LDR R0, =USART1_CR1
ORR R0, R0, #0x08
STR R0, [R0]
; 清除GPIOB的pin5
LDR R1, =GPIOB_BSRR
BIC R1, R1, #(1<<5)
数据打包协议处理
c复制// 将4个字节打包为32位字
uint32_t pack_bytes(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) {
uint32_t result;
__asm volatile(
"AND %[out], %[b0], #0xFF \n\t"
"ORR %[out], %[out], %[b1], LSL #8 \n\t"
"ORR %[out], %[out], %[b2], LSL #16 \n\t"
"ORR %[out], %[out], %[b3], LSL #24"
: [out] "=r" (result)
: [b0] "r" (b0), [b1] "r" (b1), [b2] "r" (b2), [b3] "r" (b3)
);
return result;
}
Cortex-M3支持五种移位操作,编码格式为:
code复制31-28 27-25 24-21 20 19-16 15-12 11-7 6-5 4-0
[cond] [000] [opcode] [S] [Rn] [Rd] [imm5] [10] [Rm]
各指令特性对比:
| 指令 | 助记符 | 移位方向 | 空位填充 | 移位范围 |
|---|---|---|---|---|
| 算术右移 | ASR | 右 | 符号位 | 1-32位 |
| 逻辑左移 | LSL | 左 | 0 | 0-31位 |
| 逻辑右移 | LSR | 右 | 0 | 1-32位 |
| 循环右移 | ROR | 右 | 移出位 | 1-31位 |
| 带扩展循环右移 | RRX | 右 | C标志 | 固定1位 |
移位指令支持两种参数指定方式:
assembly复制LSL R0, R1, R2 ; 寄存器指定移位量(R2低8位有效)
LSR R3, R4, #5 ; 立即数指定移位量
特殊案例处理:
快速乘除法替代
assembly复制; 乘以35的优化实现 (35x = 32x + 2x + x)
MOV R0, R1, LSL #5 ; R0 = R1*32
ADD R0, R0, R1, LSL #1 ; + R1*2
ADD R0, R0, R1 ; + R1
; 除以8的无符号除法
LSR R2, R3, #3
位域提取高效实现
c复制// 提取bit10-bit19并符号扩展
int32_t extract_signed_field(uint32_t value) {
int32_t result;
__asm volatile(
"ASR %[out], %[in], #10 \n\t"
"BFI %[out], %[out], #0, #10"
: [out] "=r" (result)
: [in] "r" (value)
);
return result;
}
Cortex-M3提供专门的位域处理指令:
assembly复制; 将R1的bit5-bit8插入R0的bit20-bit23
BFI R0, R1, #20, #4
; 提取R2的bit12-bit15并零扩展
UBFX R3, R2, #12, #4
TST和TEQ指令专为条件判断优化:
assembly复制TST R0, #0x08 ; 测试bit3,等效于ANDS但不保存结果
BNE pin_set ; 若bit3=1则跳转
TEQ R1, R2 ; 比较相等性,不影响V/C标志
BEQ values_equal
复杂位操作的高效实现:
assembly复制; 将R0低4位与R1高4位组合
AND R2, R0, #0x0F
AND R3, R1, #0xF0
ORR R4, R2, R3
; 循环移位加密算法片段
EOR R0, R0, R0, ROR #16
AND R0, R0, #0xFFFF
寄存器使用限制:
立即数范围问题:
assembly复制AND R0, R1, #0xFFFFFF00 ; 错误:立即数超出编码范围
; 正确替代方案:
MOVW R0, #0xFF00
MOVT R0, #0xFFFF
AND R0, R1, R0
标志位意外修改:
c复制// 危险的标志位依赖
uint32_t safe_add(uint32_t a, uint32_t b) {
uint32_t sum;
__asm volatile(
"ADDS %[sum], %[a], %[b] \n\t"
"AND %[sum], %[sum], #0x0FFFFFFF" // 意外清除N标志!
: [sum] "=r" (sum)
: [a] "r" (a), [b] "r" (b)
);
return sum;
}
指令配对原则:
移位替代乘除:
位域操作优化:
assembly复制; 低效实现:
AND R0, R1, #0x1F
LSL R0, R0, #3
; 高效实现:
UBFX R0, R1, #0, #5 ; 提取bit0-bit4
LSL R0, R0, #3 ; 乘以8
指令单步调试:
反汇编验证:
bash复制arm-none-eabi-objdump -d firmware.elf
条件执行诊断:
assembly复制; 条件执行诊断代码片段
CMP R0, #10
ITT EQ
ANDEQ R1, R1, #0xFF
ORREQ R2, R2, #0x100
掌握Cortex-M3的逻辑与移位指令需要理解其二进制编码格式、执行时序和标志位影响。在实际开发中,建议结合芯片参考手册和编译器优化报告,针对具体应用场景选择最优指令序列。这些基础指令的高效使用,往往是提升嵌入式系统性能的关键所在。