Search code examples
assemblyarmabi

Why CPSR register is not saved during function call in ARM ABI?


Suppose I change the CPSR register in the caller fucntion by instruction like SUBS R0, R0, #1, where R0 is exactly equals to 1, then call a function using beq cpsr_test. In the callee function, the Z flag of CPSR is still set, right? Then callee function's behavior is affected by caller, so why all programs do not save CPSR during function call(even context switch)?

caller/callee example:

caller  mov     r0, #1
        subs    r0, r0, #1 // Z flag set 
        b       callee

callee  mov     r2, #3
        // something here that have not update cpsr
        beq     label_1    // caller's Z flag is set
        b       label_2

label_1
label_2

kernel space context switch example(not save cpsr either):

/* arm_context_switch(addr_t *old_sp, addr_t new_sp) */
FUNCTION(arm_context_switch)
/* save non callee trashed supervisor registers */
/* spsr and user mode registers are saved and restored in the iframe by exceptions.S */
push    { r4-r11, lr }

/* save old sp */
str     sp, [r0]

/* load new regs */
mov     sp, r1
pop     { r4-r11, lr }
bx      lr

I saw this post: how to understand the function of “__swtich_ to” for contex-switch in the ARM linux, I know that R0-R3 is not need to saved saved because of contention, but still can't get the point of not saving CPSR. Help please.


Solution

  • Programs running on ARM generally follow the ARM calling convention.

    parameters are passed by placing the parameter values into registers R0 through R3 before calling the subroutine, and a subroutine returns a value by placing it into R0 before returning. [...] we'd place any additional parameters onto the stack before entering the subroutine (with the earlier parameters pushed last onto the stack, so that the fifth parameter is on the stack's top (referenced by SP).

    Each subroutine is allowed to alter R0 through R3 as it wishes; but if it uses R4 through R12, it must restore them to their previous values. It must also restore the stack pointer R13, effectively removing everything from the stack. It may change the link pointer R14.

    Note that no mention is made of the flags register: CPSR.
    Even a more formal document like The ARM-THUMB Procedure Call Standard doesn't.
    It is implied that flags are not saved between function calls.

    When doing a context switch, CPSR is saved as can be seen in the ARM documentation.