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.
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.