Ach*_*med 3 c linux assembly system-calls arm64
我正在研究 Aarch64 arm 位 cpu 的系统调用处理程序函数,我正在研究它是如何在 x86 程序集中完成的,但我无法弄清楚它在 Aarch64 程序集中如何完成。
我正在 github 上查看此示例:https : //github.com/rockytriton/LLD/blob/main/linux_os/part1/src/start.S,它是用 x86 程序集编写的。
.globl _syscall
_syscall:
movq %rdi, %rax
movq %rsi, %rdi
movq %rdx, %rsi
movq %rcx, %rdx
movq %r8, %r10
movq %r9, %r8
movq 8(%rsp), %r9
syscall
ret
Run Code Online (Sandbox Code Playgroud)
并且此答案中显示的一些在线等价物不满足相同的函数调用设计。这是用 Aarch64 程序集编写的。
/* Generated by gensyscalls.py. Do not edit. */
#include <private/bionic_asm.h>
.hidden __set_errno
ENTRY(write)
mov x8, __NR_write
svc #0
cmn x0, #(MAX_ERRNO + 1)
cneg x0, x0, hi
b.hi __set_errno
ret
END(write)
Run Code Online (Sandbox Code Playgroud)
到目前为止,我有这个代码(从 x86 移植到 Aarch64 很差):
.globl _syscall
_syscall:
mov x8, r7
svc #0
cmn x0, #(4095 + 1)
cneg x0, x0, hi
ret
Run Code Online (Sandbox Code Playgroud)
它不工作,但我已经试过然而,讽刺的是,当我组装它,它似乎并不像名册的名字r7,我完全不明白为什么,因为这应该是函数调用的参数(见下文)。
我在我的 C 程序的头文件中有一个函数布局,如下所示:unsigned long _syscall(int num, void *a0, void *a1, void *a2, void *a3, void *a4, void *a5)任何人对如何在 Aarch64 程序集中重新创建相同的系统调用处理程序功能有任何想法 - 我的移植尝试没有成功。我对此相当迷茫,因为组装不是我的强项 - 具有讽刺意味的是,这是我项目中唯一需要的组装。
非常感谢!
如另一个答案所示,当您使用 发出系统调用时svc,您应该将系统调用编号输入x8,并将参数输入x0-x5。
但是,根据ARM ABI,参数在 registers 中传递给您的 C 函数,x0-x7从左到右。(文档使用r0-r7令人困惑;这意味着x0-x7或w0-w7根据它们是 64 位还是 32 位值r7。AArch64 没有命名或类似的寄存器,尽管 ARM32 有。)
所以系统调用号在w0它应该在的时候出现x8(或等效地w8,因为它总是一个正的 32 位数字);第一个参数a0是在x1什么时候需要在x0;等等。所以你需要一些代码来调整它们。
mov w8, w0
mov x0, x1
mov x1, x2
mov x2, x3
mov x3, x4
mov x4, x5
mov x5, x6
svc #0
Run Code Online (Sandbox Code Playgroud)
(如果您将num参数放在参数列表的末尾而不是开头,则可以省去一些麻烦,如果您不想更改现有代码,也许可以借助宏。那么您只需要mov w8, w6 ; svc #0.)
另一方面,在 中svc #0留下一个返回值x0。但是,如果系统调用失败,x0则不包含-1而是errno应该返回的代码的否定(在 -1 和 -4095 之间)。此测试与检查作为无符号值的返回值是否大于-4096. 当发生这种情况时,通常您希望设置errno为-x0然后设置x0为-1(以便-1从 syscall 函数返回)。
目前尚不清楚您希望syscall函数在出现错误时如何表现。使用您的代码,它将否定负错误代码,然后通过将其留在 中来返回它x0,这可能不是您想要的。例如,如果您尝试使用您syscall的文件打开文件,但ENOENT由于文件不存在而失败,则在系统调用返回时x0将包含-2。您的测试将否定它,您的syscall函数将返回2,这与 open 成功并在 fd 2 上打开文件无法区分。您可能想提出其他一些机制,但我不知道您是否想要一个全局变量喜欢errno什么的。