ARM THUMB2函数可以比较多个值

时间:2017-01-05 11:24:35

标签: arm thumb

我对ARM很陌生,我希望将寄存器中的值与已知十六进制值的选择进行比较。目前我正在使用单独的CMP指令执行此操作,因此代码如下所示:

;stuff

CMP r2, #0x41

CMP r2, #0x45

CMP r2, #0x49

etc...
很明显,经过一段时间后这会非常繁琐,我认为必须有一种方法可以同时将r2中的值与一些十六进制值进行比较。

新手问题的警告,感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

通常,您会查看有效值范围。

  1. 检查值是否在范围内。
  2. 从寄存器中减去最低值。
  3. 使用修改后的值作为数组索引;数组可能有一个值键或只是是/否。
  4. 只有当范围内的某些值无效并且数组应该相当密集时,才需要执行步骤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兼容功能),但错误处理也是混合的,不太清楚。