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

汇编中寄存器与十六进制值比较失效及简化实现咨询

问题分析与解决方案

兄弟,你踩了一个典型的键值编码不匹配的坑!

你提到已经把按键“2”对应的0x00000002存入r1,但你的比较逻辑用的是0x30-0x39——这是ASCII字符'0'-'9'的十六进制值,和你存在r1里的原始按键硬件值完全不是一回事,自然不会触发跳转啦!


第一步:修正比较逻辑

有两种思路可以解决这个匹配问题:

思路1:直接用原始键值做比较

既然r1里存的是按键对应的硬件键值(比如数字“1”对应0x1,“2”对应0x2...“9”对应0x9,“0”可能对应0xA或0x0,取决于你的输入驱动逻辑),那把比较的立即数改成对应的原始值就行:

cmp r1, #0x01  ; 匹配按键"1"
beq savekey
cmp r1, #0x02  ; 匹配按键"2"
beq savekey
cmp r1, #0x03  ; 匹配按键"3"
beq savekey
; ... 依次类推到按键"9"和"0"
cmp r1, #0x09  ; 匹配按键"9"
beq savekey
cmp r1, #0x00  ; 如果"0"键对应原始值0x0的话
beq savekey

思路2:先将原始键值转为ASCII码再比较

如果你的业务逻辑最终需要处理ASCII码,不如先把r1里的原始键值转换成对应的ASCII码,再用你原来的比较逻辑:

; 假设数字键"1"对应原始值0x1,"0"对应0x0
add r1, r1, #0x30  ; 原始值+0x30 = 对应ASCII码(比如0x1+0x30=0x31='1')

; 接下来用你原来的比较逻辑就行
cmp r1, #0x30
beq savekey
cmp r1, #0x31
beq savekey
; ... 直到#0x39

第二步:用更简洁的写法替代逐个判断

逐个cmp+beq太啰嗦了,利用数字键值的连续性,我们可以用范围判断来简化代码:

方案1:范围边界判断(通用写法)

如果原始键值是连续的(比如0x0-0x9对应数字0-9),直接判断是否在这个区间内:

cmp r1, #0x0
blt skip_save  ; 小于0,不是数字键,跳过
cmp r1, #0x9
bgt skip_save  ; 大于9,不是数字键,跳过
b savekey      ; 走到这里说明是数字键,直接跳转

skip_save:
; 非数字按键的处理逻辑

如果是ASCII码的范围(0x30-0x39),逻辑完全一样,只是把比较的立即数换成0x30和0x39即可。

方案2:位运算快速判断(ARM架构优化)

对于ARM架构,还可以用位运算快速判断是否是0-9的数值(假设r1的高24位都是0):

; 针对原始键值0x0-0x9的情况
ands r2, r1, #0xF0  ; 0-9的二进制高4位都是0,与0xF0结果为0
beq savekey         ; 结果为0则跳转

; 针对ASCII码0x30-0x39的情况
sub r2, r1, #0x30   ; 先把ASCII码转成0-9的数值
ands r2, r2, #0xF0
beq savekey

这种写法比两次cmp更高效,适合对性能有要求的场景。


内容的提问来源于stack exchange,提问作者Exchange_programming

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:26:26