Search code examples
assemblymodemov

ARM Cortext A9, MOVS instruction cause operation mode switching


I have a piece of ARM Cortex A9 assembly code:

@ Switch to FIQ mode and keep interrupts disabled (required to have access to SPSR register)
@ NOTE:  The code following this point cannot result in a change to the FIQ mode SP

MSR     CPSR_c,#(ESAL_AR_ISR_CPSR_FIQ_MODE | ESAL_AR_ISR_CPSR_IRQ_BIT | ESAL_AR_ISR_CPSR_FIQ_BIT)

@ Get return address and SPSR from stack

LDR     lr,[r0,#ESAL_AR_STK_MIN_PC_OFFSET]
LDR     r1,[r0,#ESAL_AR_STK_MIN_SPSR_OFFSET]    

@ Update SPSR

MSR     SPSR_cxsf, r1    

@ Restore minimal registers

LDMIA   r0,{r0-r3}

@ Return to point of interrupt

MOVS    pc,lr

Before switching to FIQ mode, it was in Sys mode. The LR pop from stack is 0x0016B1C4. Here is my observation: after instruction "MOVS pc, lr", pc jumps to 0x0016B1C4, at the same time, ARM operation mode also switches to Sys mode. The CPSR value changes to 0x1F from 0x200000d1.

My question is how instruction "MOVS" changes ARM operation mode?

Thanks.


Solution

  • Please read the ARM documentation before asking at StackOverflow...

    Under mov

    The destination register. If S is specified and is the PC, see SUBS PC, LR and related instructions (ARM) on page B9-2010. This register can be the SP or PC.

    then following that link

    The SUBS PC, LR, # instruction provides an exception return without the use of the stack. It subtracts the immediate constant from LR, branches to the resulting address, and also copies the SPSR to the CPSR. The ARM instruction set contains similar instructions based on other data-processing operations, or with a wider range of operands, or both. ARM deprecates using these other instructions, except for MOVS PC, LR .

    So the answer is because that is the definition of the operation of that instruction.