6.6.4. スーパーバイザモードでの SVC の使用

SVC 命令が実行される場合、以下のようになります。

  1. プロセッサがスーパーバイザモードに入ります。

  2. CPSRspsr_SVC に格納されます。

  3. 復帰アドレスが lr_SVC に格納されます(例外に対するプロセッサの応答参照)。

プロセッサが既にスーパーバイザモードにあるときは、lr_SVCspsr_SVC が破壊されます。

スーパーバイザモードで SVC を呼び出す場合は、リンクレジスタと SPSR の元の値が失われないように、lr_SVC および spsr_SVC を保存しておく必要があります。例えば、特定の SVC 番号のハンドラルーチンが別の SVC を呼び出す場合は、そのハンドラルーチンで lr_SVCspsr_SVC の両方をスタックに格納する必要があります。この動作の結果、ハンドラが呼び出されるごとに、ハンドラを呼び出した SVC に続く命令に復帰するために必要な情報が保存されることが保証されます。Example 6.9 は、この方法を示しています。

Example 6.9. SVC ハンドラ

        AREA SVC_Area, CODE, READONLY

    PRESERVE8

    EXPORT SVC_Handler
    IMPORT C_SVC_Handler

T_bit EQU 0x20

SVC_Handler

    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.This is only really needed in case of
                                  ; nested SVCs.

        ; the next two instructions only work for SVC calls from ARM state.
        ; See "Example 6‑18 on page 6‑36" for a version that works for calls from either ARM or Thumb.

    LDR      r0,[lr,#-4]          ; Calculate address of SVC instruction and load it into r0.
    BIC      r0,r0,#0xFF000000    ; Mask off top 8 bits of instruction to give SVC number.

        ; r0 now contains SVC number
        ; r1 now contains pointer to stacked registers

    BL       C_SVC_Handler        ; Call C routine to handle the SVC.
    LDMFD    sp!, {r0, r3}        ; Get spsr from stack.
    MSR      spsr_cf, r0          ; Restore spsr.
    LDMFD    sp!, {r0-r3,r12,pc}^ ; Restore registers and return.

     END

C/C++ で記述した入れ子構造の SVC

C または C++ で入れ子になった SVC を記述できます。ARM コンパイラによって生成されるコードは、必要に応じて lr_SVC のストアと再ロードを実行します。

Copyright © 2002-2006 ARM Limited. All rights reserved.ARM DUI 0203GJ
Non-Confidential