ARM汇编TST指令含义及等效C语言实现方式咨询
ARMv6 tst 指令通俗解释
ARM 架构的 tst 是按位测试指令,核心逻辑是将两个操作数做按位与运算,仅修改 CPSR(程序状态寄存器)的标志位,不会保存运算结果到寄存器。
你查到的「对寄存器与自身执行逻辑与运算」是 tst 的特殊用法(比如 tst r2, r2,用来检测 r2 本身是否为 0 或者负数),你代码中用的 tst r2, #立即数 属于更通用的用法:用来检测寄存器中特定的一个或多个bit是否为1。
运算后核心关注两个标志位:
- ZF(零标志位):按位与结果为 0 时 ZF 置 1,否则置 0
- NF(负标志位):按位与结果最高位为 1 时 NF 置 1,否则置 0
你代码中的指令逻辑
你代码里的 tst r2, #0x80000000 是把 r2 存储的值和 0x80000000(32位无符号整数的最高位,对应有符号int的符号位)做按位与。后续的 bne wait$ 是「如果ZF标志位不为1(也就是按位与结果不为0)就跳转到wait$标签」,逻辑等价于:只要r2的最高位是1,就一直循环等待,直到最高位变为0才退出循环。
你写的C代码问题&正确等效写法
你写的 if(valRead & 0x80000000 != 0){} 出错是因为C语言运算符优先级问题:!= 的优先级高于 &,你的代码实际执行逻辑是 if(valRead & (0x80000000 != 0)),等价于 if(valRead & 1),完全不符合预期。
正确的C语言等效代码
整段汇编对应的C实现如下:
#include <stdint.h> // 假设r0是外设寄存器基地址,用volatile避免编译器优化掉循环读操作 volatile uint32_t *reg_base = (volatile uint32_t *)r0; // 24字节偏移对应uint32_t类型的索引6:6*4字节=24字节 while ((reg_base[6] & 0x80000000U) != 0) { // 空循环等待位清零 }
如果单独对应 tst + bne 的分支逻辑,写法为:
uint32_t valRead = reg_base[6]; if ((valRead & 0x80000000U) != 0) { goto wait$; }
内容的提问来源于stack exchange,提问作者Packa
相关产品推荐
相关产品推荐

