Search code examples
assemblyarmraspberry-pibare-metalcmp

ARM Assembly - CMP wrong output


I'm working on a program in ARM assembly (Raspberry pi), but I have a problem.

I have this code, but the lower part is always executing (skip$).

mov r1, #3
mov r3, #4
add r2, r1, r3
bl Debug
cmp r2, #0x0A
ble skip$
    mov r0, #10
    sub r0, r0, r1
    mov r3, r0

    bl Debug
skip$:

What am I missing?

The Debug function just sends r0 - r4 trough UART to my pc.

When I run this, at the end, r3 is 7. Which should be still 4.

Thanks in advance

Laurens Wuyts

Edit: Here are the other functions used.

Debug:
push {r0 - r4, lr}
    mov r4, r0

    mov r0, #10
    bl UART_write
    mov r0, r4
    bl UART_write

    mov r0, #11
    bl UART_write
    mov r0, r1
    bl UART_write

    mov r0, #12
    bl UART_write
    mov r0, r2
    bl UART_write

    mov r0, #13
    bl UART_write
    mov r0, r3
    bl UART_write
pop {r0 - r4, pc}

UART_write:
    push {r0 - r2, lr}
    ldr r1, =UART0_FR

    wait_write$:
        ldr r2, [r1]
        tst r2, #0x20
    bne wait_write$

    ldr r1, =UART0_DR
    and r0, #0x000000ff
    str r0, [r1]

    pop {r0 - r2, pc}

2nd Edit: I've used this code for the setup of the stack pointer.

setup_stack:
    mov       r0, #0xD1       @ FIQ
    msr       cpsr, r0
    ldr       sp, =stack_fiq
    mov       r0, #0xD2       @ IRQ
    msr       cpsr, r0
    ldr       sp, =stack_irq
    mov       r0, #0xD7       @ ABT
    msr       cpsr, r0
    ldr       sp, =stack_abt
    mov       r0, #0xDB       @ UND
    msr       cpsr, r0
    ldr       sp, =stack_und
    mov       r0, #0xDF       @ SYS
    msr       cpsr, r0
    ldr       sp, =stack_sys
    mov       r0, #0xD3       @ SVC
    msr       cpsr, r0
    ldr       sp, =stack_svc
    mov       pc, lr

And this is my linker:

.= ALIGN(0x1000);

/* Stack space */
. = . + 0x800;
stack_svc = .;
. = . + 0x800;
stack_und = .;
. = . + 0x800;
stack_abt = .;
. = . + 0x800;
stack_irq = .;
. = . + 0x800;
stack_fiq = .;
. = . + 0x400000;
stack_sys = .;

Solution

  • I found the problem (and answer) of this question.

    The problem was, that I was reading a byte from and address using ldr, so the output word had some garbage at the top 24 bits.

    Instead of ldr I should've used ldrb (load byte).

    The UART0_write function only sends the lowest byte of the register, so it looked right.

    Laurens