5.21 Using SVCs in Supervisor mode

If you call an SVC while in Supervisor mode you must store SVC LR and SPSR to ensure that their original values are not lost.

When an SVC instruction is executed:

  1. The processor enters Supervisor mode.

  2. The CPSR is stored into the SVC SPSR.

  3. The return address is stored in the SVC LR.

If the processor is already in Supervisor mode, the SVC LR and SPSR are corrupted, unless you store them.

For example, if the handler routine for a particular SVC number calls another SVC, you must ensure that the handler routine stores both SVC LR and SPSR on the stack. This guarantees that each invocation of the handler saves the information required to return to the instruction following the SVC that invoked it. The following example shows how to do this.

SVC Handler

    AREA SVC_Area, CODE, READONLY
    PRESERVE8
    EXPORT SVC_Handler
    IMPORT C_SVC_Handler
T_bit EQU 0x20
SVC_Handler
    PUSH     {R0-R3,R12,lr}       ; Store registers.
    MOV      R1, sp               ; Set pointer to parameters.
    MRS      R0, SPSR             ; Get SPSR.
    PUSH     {R0,R3}              ; Store SPSR onto stack and another
                                  ; register to maintain
                                  ; 8-byte-aligned stack. Only 
                                  ; required for nested SVCs.
    TST      R0,#0x20             ; Occurred in Thumb state?
    LDRHNE   R0,[lr,#-2]          ; Yes: load halfword and...
    BICNE    R0,R0,#0xFF00        ; ...extract comment field.
    LDREQ    R0,[lr,#-4]          ; No: load word and...
    BICEQ    R0,R0,#0xFF000000    ; ...extract comment field.
                                  ; R0 now contains SVC number
                                  ; R1 now contains pointer to stacked 
                                  ; registers.
    BL       C_SVC_Handler        ; Call C routine to handle the SVC.
    POP      {R0,R3}              ; Get SPSR from stack.
    MSR      SPSR_cf, R0          ; Restore SPSR.
    LDM      sp!, {R0-R3,R12,pc}^ ; Restore registers and return.
    END

Nested SVCs in C and C++

You can write nested SVCs in C or C++. Code generated by the compiler stores and reloads lr_SVC as necessary.

Non-ConfidentialPDF file icon PDF versionARM DUI0471M
Copyright © 2010-2016 ARM Limited or its affiliates. All rights reserved.