📄 system.h.txt
字号:
any problems, send mails to sindybear@163.com
相关文件
这是最为重要的一个宏,经过它以后,进程就经过了切换。
#define switch_to(prev,next,last) do { \
asm volatile("pushl %%esi\n\t" //这是参数的位置(规定)
"pushl %%edi\n\t" //这是参数的位置(规定)
"pushl %%ebp\n\t" //子函数调用必须使用的寄存器(规定)
"movl %%esp,%0\n\t" //保存prev进程的栈指针esp到task_struct->thread.esp
"movl %3,%%esp\n\t" //将next进程的thread.esp放入esp寄存器
"movl $1f,%1\n\t" //存储返回指针,也就是加####的行
"pushl %4\n\t"
"jmp __switch_to\n" 进行一次函数调用
########## "1:\t" \
"popl %%ebp\n\t" \
"popl %%edi\n\t" \
"popl %%esi\n\t" \
:"=m" (prev->thread.esp),"=m" (prev->thread.eip), \
"=b" (last) \
:"m" (next->thread.esp),"m" (next->thread.eip), \
"a" (prev), "d" (next), \
"b" (prev)); \
} while (0)
这里要注意一点,这个宏的前面几行,其作用只是为函数__switch_to建立一个合适的参数环境。
按照分析,我们可以肯定,一个函数调用,其参数结构是固定的,也就是哪一个参数使用哪一个寄存器的
顺序是固定的。另外,ebp寄存器是用来计数函数调用的层次的,不能用来传递参数,这里调用的函数
__switch_to有两个参数,也就是prev,next,他们分别在esi,edi中,将它们压入堆栈,在将ebp压入堆栈
最后将一个返回地址压入堆栈,这就可以建立一个函数调用的全部结构,然后调用jmp,就可以使用函数了
千万注意一点,绝对不能再使用call,这就会导致在一次压栈操作,就会重复了。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -