linux - 识别arm中的系统调用

标签 linux x86 arm system-calls

当我们查看 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 指令的伪代码及其确切编码 herehere ,您甚至可以模拟说明:Alastair Reid 写了几篇引人入胜的文章 here关于 ISA 正式规范。

关于linux - 识别arm中的系统调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60052690/

相关文章:

gcc - 基于 x86-64 汇编的索引寻址和段错误

compiler-construction - 为 x86 寻找 16 位 c 编译器

c - 在 ARM7TDMI 上获取参数地址时 GCC 是否损坏?

arm - 使用 llvm 从桌面交叉编译到 arm

linux - Avconv广播视频流

python - 为什么远程部署路径中的 $PATH 与远程系统中的 $PATH 不同?

linux - awk 命令输出到文本文件

linux - X86 汇编 - 结构点 - 未正确存储/返回?

assembly - 如何设置 ARM 堆栈框架以便 GDB 可以遍历它?

c++ - 在 C++ 中使用 sprintf() 和 sscanf() 时出现意外行为?