You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 21:15:05