linux 经典进程切换实现代码

extern _inline void switch_to(int n)
{
unsigned short __tmp;
__tmp = (unsigned short)_TSS(n);

_asm {
  mov ebx, offset task
  mov eax, n
  mov ecx, [ebx+eax*4]
  cmp ecx, current/* 任务n 是当前任务吗?(current ==task[n]?) */
  je l1 /* 是,则什么都不做,退出。*/
  xchg ecx,current/* current = task[n]; */
  /*执行长跳转,造成任务切换 (头大了很长时间,多多包涵)*/
  mov ax, __tmp
  mov word ptr ds:[lcs],ax
  _emit 0xea
  _emit 0  // ip
  _emit 0
  _emit 0
  _emit 0
lcs: _emit 0  // cs
  _emit 0
// 在任务切换回来后才会继续执行下面的语句。
  cmp last_task_used_math,ecx /* 新任务上次使用过协处理器吗?*/
  jne l1
  clts/* 新任务上次使用过协处理器,则清cr0 的TS 标志。*/
}
l1: ;
}

上面这段函数就是linux用来切换任务的函数。

刚开始阅读时,对红色的这段非常不理解。

在查阅了一些资料后,终于恍然大悟

资料:

jmp far F000:E05B 翻成机器 码就是 0xEA 0x5B 0xE0 0x00 0xF0

_emit指令就是直接将后面的1字节内容输出。

根据资料,我就知道了

_emit 0xEA就是jmp

紧跟在jmp后面的4字节就是IP(偏移值),再接下来的2字节就是段选择符。

mov word ptr ds:[lcs],ax。就是将ax的内容移动到上面提到的cs中,而此时ax内的内容就是tss中当前任务的cs值



你可能感兴趣的:(linux)