6.6.5. Calling SVCs from an application

You can call an SVC from assembly language or C/C++.

In assembly language, set up any required register values and issue the relevant SVC. For example:


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

The SVC instruction can be conditionally executed, as can almost all ARM instructions.

From C/C++, declare the SVC as an __SVC function, and call it. For example:

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

This enables an SVC to be compiled inline, without additional calling overhead, provided that:

The parameters are passed to the SVC as if the SVC were a real function call. However, if there are between two and four return values, you must tell the compiler that the return values are being returned in a structure, and use the __value_in_regs directive. This is because a struct-valued function is usually treated as if it were a void function whose first argument is the address where the result structure must be placed.

Example 6.10 and Example 6.11 show an SVC handler that provides SVC numbers 0x0, 0x1, 0x2 and 0x3. SVCs 0x0 and 0x1 each take two integer parameters and return a single result. SVC 0x2 takes four parameters and returns a single result. SVC 0x3 takes four parameters and returns four results. This example is in the main examples directory, in ...\svc\main.c. and ...\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 0203G
Non-Confidential