assembly - 为什么linux在entry_SYSCALL_64函数中从rcx寄存器读取ip寄存器?

标签 assembly linux-kernel operating-system system-calls cpu-registers

我正在研究linux中的系统调用处理过程。

我发现当用户进程运行syscall指令来调用系统调用时,会调用entry_SYSCALL_64函数。

该函数保存中断帧。

但是,当它推送 ip 到中断帧时,它读取的不是 rip 而是 rcx。

此代码已在下面。

ENTRY(entry_SYSCALL_64)
  UNWIND_HINT_EMPTY
  /*
   * Interrupts are off on entry.
   * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,
   * it is too small to ever cause noticeable irq latency.
   */

  swapgs
  /*
   * This path is only taken when PAGE_TABLE_ISOLATION is disabled so it
   * is not required to switch CR3.
   */
  movq  %rsp, PER_CPU_VAR(rsp_scratch)
  movq  PER_CPU_VAR(cpu_current_top_of_stack), %rsp

  /* Construct struct pt_regs on stack */
  pushq $__USER_DS      /* pt_regs->ss */
  pushq PER_CPU_VAR(rsp_scratch)  /* pt_regs->sp */
  pushq %r11        /* pt_regs->flags */
  pushq $__USER_CS      /* pt_regs->cs */
  pushq %rcx        /* pt_regs->ip ********************************** */
GLOBAL(entry_SYSCALL_64_after_hwframe)
  pushq %rax        /* pt_regs->orig_ax */

  PUSH_AND_CLEAR_REGS rax=$-ENOSYS

  TRACE_IRQS_OFF

  /* IRQs are off. */
  movq  %rsp, %rdi
  call  do_syscall_64   /* returns with IRQs disabled */
  ....

我在重要的一行中输入了这么多“*”。

在注释中,它说它保存了ip寄存器,并且这个偏移量是正确的ip偏移量。

但是,它读取了 rcx...

有谁知道为什么吗?

最佳答案

因为the syscall instruction在进入内核之前将syscall后面的指令的地址存储到RCX中。

关于assembly - 为什么linux在entry_SYSCALL_64函数中从rcx寄存器读取ip寄存器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49358425/

相关文章:

linux - CPU 能否在子进程执行时将进程保持在挂起状态 10 秒?

c++ - 我可以控制特定的VC++编译器优化吗?

linux - 何时在 linux 内核中使用内核线程与工作队列

linux - 如何将内核调试信息构建为单独的文件?

compiler-construction - 有什么能阻止 GPU 开发人员实现(几乎)完全驻留在 GPU 上的操作系统吗?

c - 事件和信号量的区别

windows - 颜色问题

c - C 中的汇编 - 向后打印特定单词

c++ - 使用 malloc 在程序集中分配的内存 - 想将其转换为 C++ 中的三维数组

c - 如何计算TCP校验和