0%

《趣谈linux操作系统》小结(十)-进程数据结构

进程数据结构

1
2
3
4

struct thread_info thread_info;
void *stack;

用户态函数栈

32位函数调用涉及到2个寄存器,ESP(Extended Stack Pointer)是栈顶指针寄存器;另外有一个寄存器 EBP(Extended Base Pointer),是栈基地址指针寄存器,指向当前栈帧的最底部。

A调用B的时候,A的栈中除了存储自身的局部变量,还存储传给B的参数,以及返回A的地址,这样B才知道返回到哪里。B返回的时候,结果存储在eax寄存器中,从栈中弹出A的地址以及给B的参数。

图片替换文本

64位系统,寄存器多一些,rax 用于保存函数调用的返回结果。栈顶指针寄存器变成了 rsp,指向栈顶位置。堆栈的 Pop 和 Push 操作会自动调整 rsp,栈基指针寄存器变成了 rbp,指向当前栈帧的起始位置。还有专门用来传递参数的寄存器,rdi、rsi、rdx、rcx、r8、r9 这 6 个寄存器,用于传递存储函数调用时的 6 个参数。如果超过 6 的时候,还是需要放到栈里面。然而,前 6 个参数有时候需要进行寻址,但是如果在寄存器里面,是没有地址的,因而还是会放到栈里面,只不过放到栈里面的操作是被调用函数做的,就是参数最终是还会放在B的栈里面。

图片替换文本

内核态函数栈

Linux 给每个 task 都分配了内核栈,使用的就是stack这个成员变量。

32位系统,内核栈大小为8K, 64位系统,大小为16K。

内核栈的结构:

图片替换文本

内核栈里面保存了当前寄存器的内容,调用返回后,再恢复寄存器的值。

在内核态里的调用都有和用户态相似的过程。

行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。