Linux kernel 在系统调用中保存在堆栈上的寄存器

Linux kernel 在系统调用中保存在堆栈上的寄存器,linux-kernel,system-calls,Linux Kernel,System Calls,调用system_call函数时,它应该检查一些参数,并根据eax中传递的参数调用system calls表中指向的函数。这是保存寄存器的部分: system_call: pushl %eax SAVE_ALL movl $0xffffe000, %ebx /* or 0xfffff000 for 4-KB stacks */ andl %esp, %ebx 为什么它两次保存eax?(在命令pushl%eax和宏SAVE_中,所有这些都保存eax)。x86-32上的标准C调用约定使用%eax从

调用system_call函数时,它应该检查一些参数,并根据eax中传递的参数调用system calls表中指向的函数。这是保存寄存器的部分:

system_call:
pushl %eax
SAVE_ALL
movl $0xffffe000, %ebx /* or 0xfffff000 for 4-KB stacks */
andl %esp, %ebx

为什么它两次保存eax?(在命令pushl%eax和宏SAVE_中,所有这些都保存eax)。

x86-32上的标准C调用约定使用
%eax
从函数返回值。Linux系统调用还将其返回值传递回
%eax
中的用户空间。这是如何在x86-32上实现的

arch/x86/entry/entry\u 32.S
中的系统调用入口点调用系统调用处理程序函数,然后用其返回值覆盖堆栈上存储的
%eax
(由
SAVE\u ALL
存储的值)。稍后,当返回到userspace时,所有寄存器的存储值都会从堆栈中弹出到寄存器中。由于由
SAVE_ALL
存储的
%eax
值被所需的返回值覆盖,当用户代码恢复执行时,它自然会在
%eax
中找到系统调用的返回值

但有时内核需要找到
%eax
的原始保存值。即使由
SAVE\u ALL
保存的值已经被覆盖,它仍然可以查看由第一个
pushl%eax
保存的值。在内核代码中,此值称为
orig\u eax
。(Grep内核源代码,您将在一些地方找到它。)


查看
arch/x86/entry/entry\u 32.S
中的
RESTORE\u REGS
宏,您将看到它使用一个
pop
参数,该参数用于在将所有保存的寄存器值弹出回寄存器后调整堆栈。您将在系统调用返回到用户空间的地方找到
RESTORE\u REGS 4
。“4”是用来去除你所问的
pushl%eax
推送的值,也被称为
orig\u eax

你具体在看什么文件,linux的版本是什么?我想是linux 2.6,它来自于关于系统调用的教程中的一张幻灯片。