1

我有一个非常简单的问题,但它把我逼到了墙角,你能帮帮我吗?

这是一个问题:如何比较 ARM 汇编中的两个有符号字节值?这是我尝试过的:

ldrsb r1, [r0], #1
ldrsb r2, [r0]
cmp r1, r2

r0 加载了字节值列表的地址,例如 10、-1、123。加载负数时,ldrsb 是否应该不 sig 扩展?我搞不清楚了

编辑:

好吧,我们应该编写一个对有符号字节值列表进行排序的程序(使用冒泡排序)。我可以弄清楚如何做到这一点,只是我不了解实际的比较(或其结果)。到目前为止,这是我的代码:

.global main

.section .data
  myNumbers: .byte 183, 374, -113, -1, 10, 101, -3, -54, 9, 7
  myNumbersEnd:

.section .text
  main:

  loop:
    mov r4, #0
    ldr r0, =myNumbers
    ldr r3, =myNumbersEnd

inner_loop:
    ldrsb r1, [r0], #1  
    ldrsb r2, [r0]  
    cmp r1, r2

    strgtb r1, [r0]
    strgtb r2, [r0, #-1]
    movgt r4, #1 @ r4 = swapped = true

    cmp r0, r3
    bne inner_loop

    cmp r4, #1
    beq loop @ keep going
exit:
    b exit
.end

也许我应该补充一点,我不是在实际的 ARM 硬件上运行此代码,而是在 ARMSim#(ARM7TDMI 处理器的模拟器)上运行此代码:http: //armsim.cs.uvic.ca/index.html

4

1 回答 1

3

好的,我会尝试打破它。

  1. r4包含“我们交换了任何东西吗?”
  2. r0r3包含输入数据的开始和结束

    loop:
      mov r4, #0
      ldr r0, =myNumbers
      ldr r3, =myNumbersEnd
    
  3. r1用 指向的字节加载和签名扩展r0,更新r0r0+1

  4. r2从更新的加载和签名扩展r0
  5. 比较两个值,这基本上r1-r2取决于结果标志的更新。

    inner_loop:
        ldrsb r1, [r0], #1  
        ldrsb r2, [r0]  
        cmp r1, r2
    
  6. 如果 r1 大于 r2,则以交换顺序存储值

  7. 同时设置交换标志(r4)

        strgtb r1, [r0]
        strgtb r2, [r0, #-1]
        movgt r4, #1 @ r4 = swapped = true
    
  8. 将我们当前的指针 inr0与 in 的结束指针进行比较r3

  9. 除非它们相等,否则下一个字节

        cmp r0, r3
        bne inner_loop
    
  10. 检查我们是否交换了任何东西,如果我们交换了,则重新开始。

        cmp r4, #1
        beq loop @ keep going
    

这里的重点是比较。如前所述, cmp 执行 op1-op2 会丢弃结果,但会根据结果设置标志,这些标志是: N = tempresult[31] (表示设置了 MSB,对于带符号的值意味着结果是有符号的. Z = tempresult == 0 (当两个值相等时为 1) C = tempresult[31] != op1[31] (用于无符号比较,表示 op1 < op2) V = op1[31] != op2[ 31] && op1[31] != tempresult[31] (类似于有符号值的进位)

接下来,您的 strgtb 首先使用标志来查看它是否真的需要执行,条件gt转换为:

Z == 0 && N == V

如果条件为真,该指令将被执行,接下来的两条指令相同。

仅供参考,您的数据集包含无效数据

  myNumbers: .byte 183, 374, -113, -1, 10, 101, -3, -54, 9, 7

183 和 374 可能会引起混淆。有效的 SIGNED 8 位值介于 -128 和 127 之间。您的代码会将 183 评估为有符号值。

于 2012-04-17T19:46:40.963 回答