Search code examples
assemblyarmcortex-mthumb

ARM asembly help for CortexM


I need to craft an ASM function. I got the most of it done,but I don't manage to get it to work as it should. I want to do a loop that runs to infinity untill a bit in a certain register(SysTick->CTRL Flag) becomes set. I used TST r5,#Val. The val is 1<<16 written as hex Then I do a BNE to loop label. It just exits the loop. r5 is from STR r5,[r0,#0] Where r0 has the SysTick CTRL address. Has anyone some complete ASM function examples. I used .global funcname I used .segment text I used .thumb_func Any other stuff to worry about?


Solution

  • First off, assembly language is specific to the assembler.

    For gnu:

    .thumb
    .globl myfun
    .thumb_func
    myfun:
        ldr r0,=0x12345678
    myfun_inner:
        ldr r1,[r0]
        cmp r1,#0
        bne my_fun_inner
        bx lr
    
    so.o:     file format elf32-littlearm
    
    
    Disassembly of section .text:
    
    00000000 <myfun>:
       0:   4802        ldr r0, [pc, #8]    ; (c <myfun_inner+0xa>)
    
    00000002 <myfun_inner>:
       2:   6801        ldr r1, [r0, #0]
       4:   2900        cmp r1, #0
       6:   d1fe        bne.n   0 <my_fun_inner>
       8:   4770        bx  lr
       a:   0000        .short  0x0000
       c:   12345678    .word   0x12345678
    

    gnu has an interesting strange label shortcut that I don't particularly like but some do:

    .thumb
    .globl myfun
    .thumb_func
    myfun:
        ldr r0,=0x12345678
    1:
        ldr r1,[r0]
        cmp r1,#0
        bne 1b
        bx lr
    

    Think of the 1b as 1 backward, you can have several 1:, 2: etc labels in this code and 1b or 1f will reference the nearest 1: forward or backward. and produces the same code:

       6:   d1fe        bne.n   0 <my_fun_inner>
    

    This is a relative jump so even though I have disassembled the object, when you link and disassemble the linked binary, that will be the same machine code:

    ldr r0,=0x12345678
    

    Is pseudo code supported by some ARM assemblers. Gas in particular will attempt to find the optimized solution:

    .thumb
    ldr r0,=0x12345678
    ldr r0,=1
    ldr r0,=0x20002
    
    00000000 <.text>:
       0:   4802        ldr r0, [pc, #8]    ; (c <.text+0xc>)
       2:   f04f 0001   mov.w   r0, #1
       6:   f04f 1002   mov.w   r0, #131074 ; 0x20002
       a:   0000        .short  0x0000
       c:   12345678    .word   0x12345678
    

    Now that was a little dangerous because it chose a thumb2 instruction, so you may wish to be ultra generic for cortex-ms (thus far, actual armv8m chips thus far)

    .cpu cortex-m0
    .thumb
    ldr r0,=0x12345678
    ldr r0,=1
    ldr r0,=0x20002
    
    00000000 <.text>:
       0:   4801        ldr r0, [pc, #4]    ; (8 <.text+0x8>)
       2:   4802        ldr r0, [pc, #8]    ; (c <.text+0xc>)
       4:   4802        ldr r0, [pc, #8]    ; (10 <.text+0x10>)
       6:   0000        .short  0x0000
       8:   12345678    .word   0x12345678
       c:   00000001    .word   0x00000001
      10:   00020002    .word   0x00020002
    

    The .short in there is an alignment spacing thing in place to keep the words word aligned. this is a cutting edge version of binutils you sometimes/often see a nop placed in there to fill space. So now perhaps the tool is filling with zeros.

    Minimal complete would be along the lines of

    .cpu cortex-m0
    .thumb
    .globl myfun
    .thumb_func
    myfun:
        ldr r0,=0x12345678
    myfun_inner:
        ldr r1,[r0]
        cmp r1,#0
        bne my_fun_inner
        bx lr
    

    And if you examine the output of gcc then you will see something closer to maximal, with a lot more syntax. So aim for somewhere in between for your personal preference. I often don't use the .cpu unless I need to as it used to default to armv4t, which is pretty much "all thumb variants" but clearly now it doesn't, so I will have to change my habits. Here again, always check your output of asm code, especially in this arm arm/thumb multiple thumb2 extensions, multiple instruction sets with the same tool.