这篇文章我们来分析switch_to()函数, 分析的代码取自linux kernel 0.11 sched.h文件, 我们只为说明原理, 所以尽量简单. 其中代码注释参考了赵炯老师<Linux内核完全注释>一书, 言归正传,下面来看switch_to()函数.
switch_to(n)将切换当前任务到任务n.首先检测任务n是不是当前任务,是则直接退出.
输入: %0 – 指向_tmp 1% - 指向_tmp.b处, 用于存放新TSS的选择符
dx – 新任务n的TSS段选择符 ecx – 新任务n的任务结构指针task[n].
_tmp用于jump指令的操作数, 其中a值是32位偏移地址, 而b的低2字节是新TSS段的选择符. 细心的读者看到a并没有被赋值,可以思考一下这是为什么
<#define switch_to(n) {\ struct {long a,b;} __tmp; \ __asm__("cmpl %%ecx,_current\n\t" \ "je 1f\n\t" \ "movw %%dx,%1\n\t" \ "xchgl %%ecx,_current\n\t" \ "ljmp %0\n\t" \ "cmpl %%ecx,_last_task_used_math\n\t" \ "jne 1f\n\t" \ "clts\n" \ "1:" \ ::"m" (*&__tmp.a),"m" (*&__tmp.b), \ "d" (_TSS(n)),"c" ((long) task[n])); \ }