Next: , Previous: PowerPC assembler, Up: Assembler and Code Words

5.27.9 ARM Assembler

The ARM assembler includes all instruction of ARM architecture version 4, and the BLX instruction from architecture 5. It does not (yet) have support for Thumb instructions. It also lacks support for any co-processors.

The assembler uses a postfix syntax with the same operand order as used in the ARM Architecture Reference Manual. Mnemonics are suffixed by a comma.

Registers are specified by their names r0 through r15, with the aliases pc, lr, sp, ip and fp provided for convenience. Note that ip refers to the“intra procedure call scratch register” (r12) and does not refer to an instruction pointer. sp refers to the ARM ABI stack pointer (r13) and not the Forth stack pointer.

Condition codes can be specified anywhere in the instruction, but will be most readable if specified just in front of the mnemonic. The 'S' flag is not a separate word, but encoded into instruction mnemonics, ie. just use adds, instead of add, if you want the status register to be updated.

The following table lists the syntax of operands for general instructions:

     Gforth          normal assembler      description
     123 #           #123                  immediate
     r12             r12                   register
     r12 4 #LSL      r12, LSL #4           shift left by immediate
     r12 r1 LSL      r12, LSL r1           shift left by register
     r12 4 #LSR      r12, LSR #4           shift right by immediate
     r12 r1 LSR      r12, LSR r1           shift right by register
     r12 4 #ASR      r12, ASR #4           arithmetic shift right
     r12 r1 ASR      r12, ASR r1           ... by register
     r12 4 #ROR      r12, ROR #4           rotate right by immediate
     r12 r1 ROR      r12, ROR r1           ... by register
     r12 RRX         r12, RRX              rotate right with extend by 1

Memory operand syntax is listed in this table:

     Gforth            normal assembler      description
     r4 ]              [r4]                  register
     r4 4 #]           [r4, #+4]             register with immediate offset
     r4 -4 #]          [r4, #-4]             with negative offset
     r4 r1 +]          [r4, +r1]             register with register offset
     r4 r1 -]          [r4, -r1]             with negated register offset
     r4 r1 2 #LSL -]   [r4, -r1, LSL #2]     with negated and shifted offset
     r4 4 #]!          [r4, #+4]!            immediate preincrement
     r4 r1 +]!         [r4, +r1]!            register preincrement
     r4 r1 -]!         [r4, +r1]!            register predecrement
     r4 r1 2 #LSL +]!  [r4, +r1, LSL #2]!    shifted preincrement
     r4 -4 ]#          [r4], #-4             immediate postdecrement
     r4 r1 ]+          [r4], r1              register postincrement
     r4 r1 ]-          [r4], -r1             register postdecrement
     r4 r1 2 #LSL ]-   [r4], -r1, LSL #2     shifted postdecrement
     ' xyz >body [#]   xyz                   PC-relative addressing

Register lists for load/store multiple instructions are started and terminated by using the words { and } respectively. Between braces, register names can be listed one by one or register ranges can be formed by using the postfix operator r-r. The ^ flag is not encoded in the register list operand, but instead directly encoded into the instruction mnemonic, ie. use ^ldm, and ^stm,.

Addressing modes for load/store multiple are not encoded as instruction suffixes, but instead specified like an addressing mode, Use one of DA, IA, DB, IB, DA!, IA!, DB! or IB!.

The following table gives some examples:

     Gforth                           normal assembler
     r4 ia  { r0 r7 r8 }  stm,        stmia    r4, {r0,r7,r8}
     r4 db!  { r0 r7 r8 }  ldm,       ldmdb    r4!, {r0,r7,r8}
     sp ia!  { r0 r15 r-r }  ^ldm,    ldmfd    sp!, {r0-r15}^

Control structure words typical for Forth assemblers are available: if, ahead, then, else, begin, until, again, while, repeat, repeat-until,. Conditions are specified in front of these words:

     r1 r2 cmp,    \ compare r1 and r2
     eq if,        \ equal?
        ...          \ code executed if r1 == r2

Example of a definition using the ARM assembler:

     abi-code my+ ( n1 n2 --  n3 )
        \ arm abi: r0=SP, r1=&FP, r2,r3,r12 saved by caller
        r0 IA!  { r2 r3 }  ldm,     \ pop r2 = n2, r3 = n1
        r3  r2  r3         add,     \ r3 = n1+n1
        r3  r0 -4 #]!      str,     \ push r3
        pc  lr             mov,     \ return to caller, new SP in r0