1

I have a very simple problem but it is driving me up the wall, would you please help me?

Here is the question: how do I compare two signed byte values in ARM assembly? This is what I tried:

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

r0 is loaded with the address of a list of byte values like 10, -1, 123. should ldrsb not sig extend when loading a negative number? I am lost

EDIT:

well we're supposed to write a program that sorts of a list of signed byte values (using bubblesort). I can figure out how to do that, it's just that I don't understand the actual comparison (or its result). This is my code so far:

.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

Maybe I should add that i am not running this code on actual ARM hardware, but on ARMSim#, a simulator for the ARM7TDMI processor: http://armsim.cs.uvic.ca/index.html

PaulK
  • 623
  • 2
  • 10
  • 22
  • 1
    ldrsb will do sign extension. Maybe you should write a bit more about your code. Everything you've shown so far is correct, so what does not work? Either your r0 is not setup correctly or you're using the wrong conditional predicates afterwards. – Nico Erfurth Apr 17 '12 at 16:30
  • You still don't tell what the actual problem is. What are the symptoms? Have you tried stepping through the program with the debugger? – starblue Apr 17 '12 at 19:45
  • Watch out for the cmp, which may not treat signed values as signed – amritkrs Dec 18 '17 at 05:50

1 Answers1

3

Ok, I'll try to break that down.

  1. r4 contains "Did we swap anything?"
  2. r0 and r3 contain start and end of the input data

    loop:
      mov r4, #0
      ldr r0, =myNumbers
      ldr r3, =myNumbersEnd
    
  3. Load and signextend r1 with the byte pointed to by r0, update r0 to r0+1

  4. Also load and signextend r2 from the updated r0
  5. Compare both values, this essentially is r1-r2 depending the result flags are updated.

    inner_loop:
        ldrsb r1, [r0], #1  
        ldrsb r2, [r0]  
        cmp r1, r2
    
  6. If r1 was greater than r2, store the values in swapped order

  7. Also set the swapped flag (r4)

        strgtb r1, [r0]
        strgtb r2, [r0, #-1]
        movgt r4, #1 @ r4 = swapped = true
    
  8. Compare our current pointer in r0 to the end pointer in r3

  9. Unless they're equal do the next byte

        cmp r0, r3
        bne inner_loop
    
  10. Check if we swapped anything, start over if we did.

        cmp r4, #1
        beq loop @ keep going
    

The key point here is the comparison. As already stated, cmp does an op1-op2 throws away the result, but sets flags according to the result, these flags are: N = tempresult[31] (Indicating that the MSB is set, for signed values that means the result is signed. Z = tempresult == 0 (Will be 1 when both values are equal) C = tempresult[31] != op1[31] (Used for unsigned compares and means op1 < op2) V = op1[31] != op2[31] && op1[31] != tempresult[31] (Something like carry for signed values)

Next your strgtb first uses the flags to see if it really needs to be executed, the condition is gt which translates into:

Z == 0 && N == V

If the condition is true, the instruction will be executed, same for the next two instructions.

FYI, your dataset contains invalid data

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

183 and 374 might cause confusion. A valid SIGNED 8-bit value is between -128 and 127. Your code will evaluate 183 as a signed value.

Nico Erfurth
  • 3,362
  • 22
  • 26