我对ARM很陌生,我希望将寄存器中的值与已知十六进制值的选择进行比较。目前我正在使用单独的CMP指令执行此操作,因此代码如下所示:
;stuff
CMP r2, #0x41
CMP r2, #0x45
CMP r2, #0x49
etc...
很明显,经过一段时间后这会非常繁琐,我认为必须有一种方法可以同时将r2中的值与一些十六进制值进行比较。
新手问题的警告,感谢您的帮助。
答案 0 :(得分:0)
通常,您会查看有效值范围。
只有当范围内的某些值无效并且数组应该相当密集时,才需要执行步骤2,3,对于您的两位十六进制应该是这种情况。
# Range check (step 1)
cmp r2, #hi_val
bhi out_of_range
cmp r2, #low_val ; optimized version is subs r2, r2, #low_val
blo out_of_range
# Adjust value (step 2)
sub r2, r2, #low_val ; removed in optimized version.
# Get check from array (step 3)
adr r0, key_array
ldrb r0, [r0, r2] ; base of array + adjusted value.
bx lr ; return w. result in r0.
# Handle not in range.
out_of_range:
mov r0, #-1
bx lr ; use 0xffffffff for out of range.
# This is a constant array included with the code.
key_array:
.byte 1, 1, 0, 1, 1, 1, 0, 0, 1, 1 # etc.
显然,您的key_array
必须更改为对您的用例有效。对于有符号和无符号值,条件代码将略有变化。
如果key_array
是二进制案例的全部,那么第二步和第三步只是return 1;
。如果low_val
为零,则您不需要减去(或进行低范围检查)。 key_array
的大小应为hi_val - low_val + 1
,否则您的范围检查逻辑可能会发生变化。
此机制用于许多'ctype'函数,例如ispunct
,但您可以在一个字节中存储多达八个值,并使用位掩码来获取您感兴趣的值。这也很容易在'C'中实现并使用编译器。可以只使用一个寄存器(R0是EABI兼容功能),但错误处理也是混合的,不太清楚。