X86任务切换机制

来源:互联网 发布:贵州中标数据网 编辑:程序博客网 时间:2024/06/06 02:29

任务切换涉及到当前任务CPU运行环境保存和新任务环境恢复两个步骤。下面用x86的GNU汇编语言分别列出了CPU环境保存和恢复的功能实现。

CPU 环境寄存器结构。

typedef struct {

   register_t Edi;

   register_t Esi;

   register_t Ebp;

   register_t Esp;

   register_t Ebx;

   register_t Edx;

   register_t Ecx;

   register_t Eax;

   register_t EFlags;

   register_t Eip;

} CONTEXT_t;

偏移量定义:

#define FRAME_OFFSET_PC         0

#define FRAME_OFFSET_PARAM0     4

#define FRAME_OFFSET_PARAM1     8

 

// offset for registers of context

#define CONTEXT_OFFSET_EDI      0

#define CONTEXT_OFFSET_ESI      4

#define CONTEXT_OFFSET_EBP      8

#define CONTEXT_OFFSET_ESP      12

#define CONTEXT_OFFSET_EBX      16

#define CONTEXT_OFFSET_EDX      20

#define CONTEXT_OFFSET_ECX      24

#define CONTEXT_OFFSET_EAX      28

#define CONTEXT_OFFSET_EFLAG    32

#define CONTEXT_OFFSET_EIP      36

 

当前任务上下文保存:

 

         .globl_context_save

         .globlcontext_save

         .align4

 

_context_save:

context_save:

   // get _p_context of context_save () for saving

   movl FRAME_OFFSET_PARAM0(%esp), %edx

 

   // save local variable registers into _p_context

   movl %ebx, (CONTEXT_OFFSET_EBX)(%edx)

   movl %esi, (CONTEXT_OFFSET_ESI)(%edx)

   movl %edi, (CONTEXT_OFFSET_EDI)(%edx)

   

   // save stack corresponding registers into _p_context

   leal FRAME_OFFSET_PARAM0(%esp), %ecx

   movl %ecx, (CONTEXT_OFFSET_ESP)(%edx)

   movl %ebp, (CONTEXT_OFFSET_EBP)(%edx)

   

   // save PC into _p_context

   movl FRAME_OFFSET_PC(%esp), %ecx

   movl %ecx, (CONTEXT_OFFSET_EIP)(%edx)

   

         //return 0 to indicate a return from context_save ()

   xorl %eax, %eax

ret

 

新任务恢复:

         .globl_context_restore

         .globlcontext_restore

         .align4

 

_context_restore:

context_restore:

         //get _p_context of context_restore ()

         movlFRAME_OFFSET_PARAM0(%esp), %ecx

        

         //take 2nd parameter of context_restore () as return value of context_save ()

         movlFRAME_OFFSET_PARAM1(%esp), %eax

        

         //restore registers from context

         movl(CONTEXT_OFFSET_EIP)(%ecx), %edx

         movl(CONTEXT_OFFSET_EBX)(%ecx), %ebx

         movl(CONTEXT_OFFSET_ESI)(%ecx), %esi

         movl(CONTEXT_OFFSET_EDI)(%ecx), %edi

         movl(CONTEXT_OFFSET_EBP)(%ecx), %ebp

         movl(CONTEXT_OFFSET_ESP)(%ecx), %esp

        

         //jump to context_save ()

jmp *%edx

 

任务切换函数:

voidcontext_switch (CONTEXT_t *_p_current, CONTEXT_t *_p_next)

{

    if (0 == _context_save (_p_current)) {

        _context_restore (_p_next, 1);

    }

}

0 0