You copied the Doc URL to your clipboard.

Determining the instruction set state from an SVC handler

An exception handler might have to determine whether the processor was in ARM or Thumb state when the exception occurred.

SVC handlers, especially, might have to read the instruction set state. This is done by examining the SPSR T-bit. This bit is set for Thumb state and clear for ARM state.

Both ARM and Thumb instruction sets have the SVC instruction. When calling SVCs from Thumb state, you must consider the following:

  • The instruction address is at lr-2, rather than lr-4.

  • The instruction itself is 16-bit, and so requires a halfword load, see the following figure.

  • The SVC number is held in 8 bits instead of the 24 bits in ARM state.

Figure 5-4 Thumb SVC instruction

The following example shows ARM code that handles an SVC exception. The range of SVC numbers accessible from Thumb state can be increased by calling SVCs dynamically.

SVC handler for exceptions in either ARM or Thumb state

    EXPORT SVC_Handler    IMPORT C_SVC_Handler
T_bit   EQU    0x20                    ; Thumb bit (5) of CPSR/SPSR.
    STMFD   sp!, {r0-r3, r12, lr}  ; Store registers
    MOV     r1, sp                 ; Set pointer to parameters
    MRS     r0, spsr               ; Get spsr
    STMFD   sp!, {r0, r3}          ; Store spsr onto stack and another
                                   ; register to maintain 
                                   ; 8-byte-aligned stack
    TST     r0, #T_bit             ; Occurred in Thumb state?
    LDRNEH  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 main part of handler
    LDMFD   sp!, {r0, r3}          ; Get spsr from stack
    MSR     SPSR_cxsf, r0          ; Restore spsr
    LDMFD   sp!, {r0-r3, r12, pc}^ ; Restore registers and return