我想检查在 glibc 中执行系统调用的代码。我发现了这样的东西:
ENTRY (syscall)
movq %rdi, %rax /* Syscall number -> rax. */
movq %rsi, %rdi /* shift arg1 - arg5. */
movq %rdx, %rsi
movq %rcx, %rdx
movq %r8, %r10
movq %r9, %r8
movq 8(%rsp),%r9 /* arg6 is on the stack. */
syscall /* Do the system call. */
cmpq $-4095, %rax /* Check %rax for error. */
jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
L(pseudo_end):
ret /* Return to caller. */
现在我的问题是:
syscall
(在cmpq
指令之前)是指令吗?- 如果是指令,
ENTRY (syscall)
是什么意思? ENTRY(我不知道 ENTRY 是什么)和指令的名称相同? - 什么是
L(pseudo_end)
?
最佳答案
syscall
是 x86-64 中的一条指令,用作 ABI for making system calls 的一部分. (32 位 ABI 使用 int 80h
或 sysenter
,在 64 位模式下也可用,但是从 64 位代码使用 32 位 ABI 是一个坏主意,尤其是对于带有指针参数的调用。)
但是还有一个C library function named syscall(2)
,系统调用 ABI 的通用包装器。您的代码显示了该函数的转储,包括将返回值解码为 errno
设置。 ENTRY(syscall)
只是意味着函数从那里开始。
L()
和 ENTRY()
是 CPP 宏。
L(pseudo_end)
只是一个可以作为跳转目标的Label。也许 SYSCALL_ERROR_LABEL
处的代码跳回到那里,尽管该代码块只是 ret
会更有效,所以它可能是以前版本的遗留物,或者用于其他用途。
关于c - syscall 是 x86_64 上的指令吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10583891/