|
发表于 2003-10-3 20:45:23
|
显示全部楼层
让我来解释一下,首先一个进程分配空间时都是以连续两个页面即8k字节进行分配的.其中task_struct结构位于低字节,栈底位于最高字节,栈向低字节延伸.
正如sorry30所说,当一个进程刚进入系统态时(被切换进入),tss的设置将esp指向当前系统堆栈的栈顶,其实确切的说,当进程从用户空间转入系统空间时esp并非指向alloc_task_struct()+8192处,原因很简单,首先esp总是指向栈顶,而堆栈转换时sorry30已经提到了,在系统堆栈需要压入一些值,比如用户的返回地址等,但是这只是少量的几个.不过从理解的角度是不能这样认为的,关键是系统堆栈已经有了东东了,虽然很少.至于"esp == alloc_task_struct() + 8192"(首先这不是严格意义上的等于,暂且算吧).很简单,allock_task_struct()返回的是task_struct的首址,也就是8k字节的最低地址,8192是8k,如果按照sorry30的理解,指向栈顶的位置就自然是
"esp == alloc_task_struct() + 8192"了,其实堆栈此时已有数据,esp要向下移,其实应该是少于esp == alloc_task_struct() + 8192
接着我来解释为什么宏current可以得到当前进程的task_struct地址:
static inline struct task_struct * get_current(void)
7 {
8 struct task_struct *current;
9 __asm__("andl %%esp,%0; ":"=r" (current) : "" (~8191UL));
10 return current;
11 }
12
13 #define current get_current()
首先current宏肯定是在系统态的用的!
上面的函数的意思就是让当前进程的系统态堆栈指针esp和~8191ul相与.什么意思呢?
esp指向的是当前进程系统堆栈的栈顶位置,相与之后的结过就是esp地址的低13位全变成了0.自然就指向了这个8k字节的最低地址了.于是也就得到了task_struct的地址.
因为给进程分配空间的时候总是以8k字节为单位的.大家按照我上面说的在纸上画画就知道了. |
|