【问题标题】:Is syscall an instruction on x86_64?syscall 是 x86_64 上的指令吗?
【发布时间】:2012-05-21 23:17:32
【问题描述】:

我想检查在 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.  */

现在我的问题是系统调用(在cmpq 指令之前)是否是指令?其次,如果是指令,ENTRY(syscall)是什么意思? ENTRY(我不知道 ENTRY 是什么)和指令的名称相同?其次,L(pseudo_end)是什么?

【问题讨论】:

  • 是的。它与 x86 中的 int 0x80 相同。
  • 请注意,通常专用代码用于每个系统调用,从常量设置%rax(保存寄存器),并跳过设置未使用的参数。

标签: c linux gcc x86-64 machine-instruction


【解决方案1】:

syscall 是 x86-64 中的指令,用作ABI for making system calls 的一部分。 (32 位 ABI 使用 int 80hsysenter,并且在 64 位模式下也可用,但在 64 位代码中使用 32 位 ABI 是个坏主意,尤其是对于带有指针参数的调用。)

但也有一个C library function named syscall(2),它是系统调用 ABI 的通用包装器。您的代码显示了该函数的转储,包括将返回值解码为errno-setting。 ENTRY(syscall) 只是意味着函数从那里开始。

L()ENTRY() 是 CPP 宏。

L(pseudo_end) 只是一个可以作为跳转目标的标签。也许SYSCALL_ERROR_LABEL 处的代码会跳回到那里,尽管将代码块只写到ret 会更有效,所以它可能是以前版本的遗物,或者用于其他用途。

【讨论】:

  • 如果这是一条实际指令,它的操作码是什么?
  • 它是 0x0F 0x05(请看 Intel 的软件开发人员手册)。
【解决方案2】:

是的,syscall 是 x86-64 上的指令。 i686上有类似的指令sysenter

ENTRY(syscall) 将是一个宏。可能会扩展为符号定义,您必须为此使用 grep。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 2016-06-29
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-09
    相关资源
    最近更新 更多