Search code examples
assemblylpcmachine-code

Does LPC111x series support MOV instruction with High registers?


UM10398 LPC111x/LPC11Cxx User manual Rev. 12.3 — 10 June 2014 says

In these instructions, Rd, and Rm must only specify R0-R7

in "28.5.5.5.3 Restrictions" in "28.5.5.5 MOV and MVN".

On the other hand, "28.5.5.5.5 Example" in UM10398 says

MOVS R0, #0x000B ; Write value of 0x000B to R0, flags get updated
MOVS R1, #0x0 ; Write value of zero to R1, flags are updated
MOV R10, R12 ; Write value in R12 to R10, flags are not updated
MOVS R3, #23 ; Write value of 23 to R3
MOV R8, SP ; Write value of stack pointer to R8
MVNS R2, R0 ; Write inverse of R0 to the R2 and update flags

In this example, R10, R12, R8 and SP are used despite of they doesn't seem R0-R7. (SP seems equivalent to R13, according to UM10398 28.4.1.3 Core registers)

One more thing is that when I read re-ejected-thumbref2.pdf, I found

MOV Rd, Rm 0 1 0 0 0 1 1 0 H1 H2 _ Rm _ _ Rd _

and this suggests High registers are available for use with MOV instruction. This document also say that

Rd or Rm must be a *high register*

about this MOV Rd, Rm instruction.

Although instructions with S (with flag update) are not on this document (in this document instructions without S are said to updating flags) and this document should be for another CPU (maybe one used in GBA, according to the URL path), I used this document as reference, hoping that instruction set of LPC111x is similar to one described in this document.

In conclusion, can I do

  • MOV R0, R1 (Low registers to Low registers)
  • MOV R8, R1 (Low registers to High registers)
  • MOV R0, R9 (High registers to Low registers)
  • MOV R8, R9 (High registers to High registers)

in LPC111x (or LPC1114FN28/102, if you need specific CPU pointed)?


Solution

  • The LPC1114FN28 has an ARM Cortex-M0 core, so its MOV instruction has no low/high restrictions on registers. However, because the Thumb instruction set didn't originally have a MOV low to low instruction, for compatibility your assembler may use an ADDS instruction for MOV R0, R1.

    For example if I assemble the following with as -mcpu=cortex-m0 t117.s:

        # .syntax unified
        .thumb
    
        MOV R0, R1
        MOV R8, R1
        MOV R0, R9
        MOV R8, R9
    

    The object file created contains the following instructions as show by objdump -d:

       0:   1c08            adds    r0, r1, #0
       2:   4688            mov     r8, r1
       4:   4648            mov     r0, r9
       6:   46c8            mov     r8, r9
    

    By uncommenting the .syntax unified directive and reassembling it the disassembly ends up as expected:

       0:   4608            mov     r0, r1
       2:   4688            mov     r8, r1
       4:   4648            mov     r0, r9
       6:   46c8            mov     r8, r9
    

    I believe the statement "In these instructions, Rd, and Rm must only specify R0-R7" was only meant to apply to the MOVS instruction which has this restriction.