【发布时间】:2020-02-01 04:44:15
【问题描述】:
我在网上找到了显示 x86_64 linux nasm 程序集的各种系统调用的图表,并且似乎总共有 380 个系统调用,但是我能找到的每本书或教程都只能找到“一些系统调用如何工作以及它们做什么?”有谁知道我在哪里可以找到有关使用 nasm 汇编器的 x86_64 linux 程序集的每个系统调用的信息?
任何帮助都会很棒。
【问题讨论】:
标签: linux assembly x86-64 system-calls
我在网上找到了显示 x86_64 linux nasm 程序集的各种系统调用的图表,并且似乎总共有 380 个系统调用,但是我能找到的每本书或教程都只能找到“一些系统调用如何工作以及它们做什么?”有谁知道我在哪里可以找到有关使用 nasm 汇编器的 x86_64 linux 程序集的每个系统调用的信息?
任何帮助都会很棒。
【问题讨论】:
标签: linux assembly x86-64 system-calls
查看 Linux 手册页(第 2 节)。 http://man7.org/linux/man-pages/dir_section_2.html
无论您使用什么汇编器(或 C 编译器)来创建 x86-64 机器代码,您可以进行的系统调用都是相同的。 (在 RAX 中输入一个调用号并运行 syscall 指令;在内核内部,它使用该编号来索引函数指针表。如果超出范围,则返回 -ENOSYS。)
使用strace ./my_program 调试您的程序以跟踪它进行的系统调用。这会在每次调用的基础上将参数和返回值解码为有意义的内容,因此您可以轻松查看是否通过例如,使系统调用返回 -EFAULT 的错误指针。 (系统调用不会引发 SIGSEGV / segfault,它们只会返回错误。)
/usr/include/asm/unistd_64.h 有实际数字。 (编译为 64 位时包含在 <asm/unistd.h> 中)。手册页将根据 C 语法记录 args。 给定 C 原型,您可以根据 x86-64 System V ABI 制定 asm ABI。 (与函数调用 ABI 相同,但第 4 个参数使用 R10 而不是 RCX,如果存在。)What are the calling conventions for UNIX & Linux system calls on i386 and x86-64
syscall(2) 是系统调用的 glibc 包装函数,the syscall man page 还记录了各种 Linux 平台(x86-64、SPARC、ARM 等)的 asm ABI,包括调用编号和 ret val 的寄存器,以及进入内核的指令。请注意,函数名称与 x86-64 syscall 指令相同纯属巧合。
没有人会费心为每个不同风格的 asm 语法的每个系统调用制作详尽的文档 - 信息都在手册页和调用约定文档中; Linux 手册页的 NOTES 部分记录了 C 库包装 API 与底层 asm 系统调用之间的差异。
另请参阅https://blog.packagecloud.io/eng/2016/04/05/the-definitive-guide-to-linux-system-calls/,了解更多包括 VDSO 的内容,以实现高效的getpid / clock_gettime,甚至无需进入内核。
但是,有些人会编译系统调用名称和 Linux x86-64 调用编号和 arg 寄存器的表格。我从来没有发现它很有用(系统调用调用约定与函数调用约定非常接近,因此很容易记住),但如果您需要,https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/ 就在那里。
POSIX 函数和原始 Linux 系统调用之间的显着差异存在于几个调用中:例如 brk / sbrk 和 getpriority,其中“nice”级别的返回值是有偏差的,因此它们不在 @ 987654344@ 错误代码范围。 但大多数系统调用都有一个与 C 库包装原型完全匹配的 ABI,在这种情况下,NOTES 部分没有提及任何内容。
【讨论】:
struct stat 与stackoverflow.com/questions/27216616/… 中发现的真实结构进行比较。结构成员st_mode 和st_nlink 的顺序在手册页中交换。跨度>