当我们查看 x86 CPU 上的汇编程序时,系统调用如下所示:
0F 05 syscall ; LINUX - sys_nanosleep
48 3D 01 F0 FF FF cmp rax, 0FFFFFFFFFFFFF001h
我们什么时候谈论 ARM CPU 系统调用在汇编程序中的约定是什么?
最佳答案
musl的源代码libc 库可能会有所帮助:所有支持的体系结构都有一个实现“系统调用”的小头文件。
x86_64 :
static __inline long __syscall0(long n)
{
unsigned long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory");
return ret;
}
Arm :
#ifdef __thumb__
/* Avoid use of r7 in asm constraints when producing thumb code,
* since it's reserved as frame pointer and might not be supported. */
#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
#define __ASM____R7__ __asm__("r7")
#define __asm_syscall(...) do { \
__asm__ __volatile__ ( "svc 0" \
: "=r"(r0) : __VA_ARGS__ : "memory"); \
return r0; \
} while (0)
#endif
Aarch64 :
#define __asm_syscall(...) do { \
__asm__ __volatile__ ( "svc 0" \
: "=r"(x0) : __VA_ARGS__ : "memory", "cc"); \
return x0; \
} while (0)
生成代码示例:
/* syscall.c */
#define __asm_syscall(...) do { \
__asm__ __volatile__ ( "svc 0" \
: "=r"(x0) : __VA_ARGS__ : "memory", "cc"); \
return x0; \
} while (0)
static inline long __syscall0(long n)
{
register long x8 __asm__("x8") = n;
register long x0 __asm__("x0");
__asm_syscall("r"(x8));
}
void test(void) {
__syscall0(1);
}
/opt/arm/9/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-objdump -D syscall.o
/opt/arm/9/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc -c -o syscall.o syscall.c
Disassembly of section .text:
0000000000000000 <__syscall0>:
0: d10043ff sub sp, sp, #0x10
4: f90007e0 str x0, [sp, #8]
8: f94007e8 ldr x8, [sp, #8]
c: d4000001 svc #0x0
10: 910043ff add sp, sp, #0x10
14: d65f03c0 ret
0000000000000018 <test>:
18: a9bf7bfd stp x29, x30, [sp, #-16]!
1c: 910003fd mov x29, sp
20: d2800020 mov x0, #0x1 // #1
24: 97fffff7 bl 0 <__syscall0>
28: d503201f nop
2c: a8c17bfd ldp x29, x30, [sp], #16
30: d65f03c0 ret
话虽如此,arm 文档实际上不能被称为垃圾,即使您发现很难找到您正在寻找的确切信息:Exploration Tools section恕我直言,他们网站的内容非常棒。
您可以找到 SVC 指令的伪代码及其确切编码 here和 here ,您甚至可以模拟说明:Alastair Reid 写了几篇引人入胜的文章 here关于 ISA 正式规范。
关于linux - 识别arm中的系统调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60052690/