#ifndef __scc
#define __scc(X) ((long) (X)) // 转为long类型
typedef long syscall_arg_t;
#endif
#define __syscall1(n,a) __syscall1(n,__scc(a))
#define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b))
#define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c)) //
继续搜索发现有多出匹配,我们关注arch/arm目录下的文件,因为ARM Cortext A7是Armv7-A指令集的32位CPU(如果是Armv8-A指令集的64位CPU则对应arch/aarch64下的文件):
static inline long __syscall3(long n, long a, long b, long c)
{
register long r7 __ASM____R7__ = n;
register long r0 __asm__("r0") = a;
register long r1 __asm__("r1") = b;
register long r2 __asm__("r2") = c;
__asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2));
}
这段代码中还有三个宏,__ASM____R7__、__asm_syscall和R7_OPERAND:
#ifdef __thumb__
#define __ASM____R7__
#define __asm_syscall(...) do { \
__asm__ __volatile__ ( "mov %1,r7 ; mov r7,%2 ; svc 0 ; mov r7,%1" \
: "=r"(r0), "=&r"((int){0}) : __VA_ARGS__ : "memory"); \
return r0; \
} while (0)
#else // __thumb__
#define __ASM____R7__ __asm__("r7")
#define __asm_syscall(...) do { \
__asm__ __volatile__ ( "svc 0" \
: "=r"(r0) : __VA_ARGS__ : "memory"); \
return r0; \
} while (0)
#endif // __thumb__
#ifdef __thumb2__
#define R7_OPERAND "rI"(r7)
#else
#define R7_OPERAND "r"(r7)
#endif
它们有两个实现版,分别对应于编译器THUMB选项的开启和关闭。这两种选项条件下的代码流程基本一致,以下仅以未开启THUMB选项为例进行分析。这两个宏展开后的__syscall3函数内容为:
static inline long __syscall3(long n, long a, long b, long c)
{
register long r7 __asm__("r7") = n; // 系统调用号
register long r0 __asm__("r0") = a; // 参数0
register long r1 __asm__("r1") = b; // 参数1
register long r2 __asm__("r2") = c; // 参数2
do { \
__asm__ __volatile__ ( "svc 0" \
: "=r"(r0) : "r"(r7), "0"(r0), "r"(r1), "r"(r2) : "memory"); \
return r0; \
} while (0);
}
这里最后的一个内嵌汇编比较复杂,它符合如下格式(具体细节可以查阅gcc内嵌汇编文档的扩展汇编说明):
asm asm-qualifiers ( AssemblerTemplate
: OutputOperands
[ : I