6.6.5. アプリケーションからの SVC の呼び出し

SWI はアセンブリ言語または C/C++ から呼び出すことができます。

アセンブリ言語では、必要なレジスタ値を設定して関連 SVC を発行します。以下に例を示します。

    MOV    r0, #65    ; load r0 with the value 65
    SVC    0x0        ; Call SVC 0x0 with parameter value in r0

SVC 命令は、ほぼすべての ARM 命令と同じように、条件付きで実行できます。

C/C++ からは SVC を __SVC 関数として宣言し、これを呼び出します。以下に例を示します。

    __svc(0) void my_svc(int);
    .
    .
    .
    my_svc(65);

これにより、以下の条件下で、呼び出しのオーバーヘッドを新たに発生させることなく SVC をインラインでコンパイルできます。

SVC が実際の関数呼び出しであるかのように、パラメータが SVC に渡されます。しかし、2 〜 4 個の戻り値がある場合には、それらの戻り値が構造体で返されることをコンパイラに通知する必要があるため、__value_in_regs ディレクティブを使用します。これは通常、struct の値を取る関数が、結果の構造体が配置されるアドレスを第 1 引数に取る void 関数と同じように処理されるためです。

Example 6.10および Example 6.11は、0x00x10x2、および 0x3 の 4 つの SVC 番号を取る SVC ハンドラを示しています。SVC 0x0 および 0x1 は、それぞれ 2 つの整数パラメータを使用し、1 つの結果を返します。SVC 0x2 は 4 つのパラメータを使用し、1 つの結果を返します。SVC 0x3 は 4 つのパラメータを使用し、4 つの結果を返します。このサンプルは、主なサンプルディレクトリ ...\svc\main.c および ...\svc\svc.h に収録されています。

Example 6.10. main.c

#include <stdio.h>
#include "svc.h"

unsigned *svc_vec = (unsigned *)0x08;
extern void SVC_Handler(void);

int main( void )
{
    int result1, result2;
    struct four_results res_3;
    Install_Handler( (unsigned) SVC_Handler, svc_vec );
    printf("result1 = multiply_two(2,4) = %d\n", result1 = multiply_two(2,4));
    printf("result2 = multiply_two(3,6) = %d\n", result2 = multiply_two(3,6));
    printf("add_two( result1, result2 ) = %d\n", add_two( result1, result2 ));
    printf("add_multiply_two(2,4,3,6) = %d\n", add_multiply_two(2,4,3,6));
    res_3 = many_operations( 12, 4, 3, 1 );
    printf("res_3.a = %d\n", res_3.a );
    printf("res_3.b = %d\n", res_3.b );
    printf("res_3.c = %d\n", res_3.c );
    printf("res_3.d = %d\n", res_3.d );
    return 0;
}

Example 6.11. svc.h

__svc(0) int multiply_two(int, int);
__svc(1) int add_two(int, int);
__svc(2) int add_multiply_two(int, int, int, int);

struct four_results
{
    int a;
    int b;
    int c;
    int d;
};

__svc(3) __value_in_regs struct four_results
    many_operations(int, int, int, int);
Copyright © 2002-2006 ARM Limited. All rights reserved.ARM DUI 0203GJ
Non-Confidential