第五章相应的汇编转换成C的分析【二】

    擦!前几天光纤被搞断了,今天下午才来修好,没网络的日子很不爽啊。

    前几天扯到哪了,哦,改用C来继续写第五章的内容了。上一篇搞定了GDT和内核栈的切换了,现在就来写8259A的设置和填充IDT的内容了。

    设置8259A的话就是一堆out指令向相应的端口写一些命令字,当然只能用汇编了,不过也能用C来封装一下,哈哈。下面这个函数就是相应的封装:

Code:
  1. void Out_Byte(u16 port,u8 value);   
  2.   
  3. void Init_8259A()   
  4. {   
  5.     Out_Byte(0x20,0x11);   
  6.     Out_Byte(0xa0,0x11);   
  7.        
  8.     Out_Byte(0x21,0x20);   
  9.     Out_Byte(0xa1,0x28);   
  10.        
  11.     Out_Byte(0x21,0x4);   
  12.     Out_Byte(0xa1,0x2);   
  13.        
  14.     Out_Byte(0x21,0x1);   
  15.     Out_Byte(0xa1,0x1);   
  16.        
  17.     Out_Byte(0x21,0xff);   
  18.     Out_Byte(0xa1,0xff);   
  19. }  

    这个Out_Byte函数自然是用汇编写了:

 Out_Byte:
  push ebp
  mov ebp,esp  
 
  push eax  
  push edx
 
  mov edx,[ebp + 8]
  mov eax,[ebp + 12]
 
  out dx,al
 
  pop edx
  pop eax
 
  pop ebp

  ret

  最后在C_Start中调用Init_8259A就完成对8259A的初始化了。

  接下来就是建立IDT并把它加载到IDTR中,并且把对应的中断处理程序写好。

  先把内中断的处理程序写好,由于有些中断没有错误码,有些有,而我们想最终用同一个函数来处理所有的内中断,所以在没有错误码的中断的压入一个值来保证统一。由下面的代码得知,每个中断处理程序还多压入了一个中断向量号。

Divide_Error:
 push 0ffffffffh
 push 0
 jmp Exception
Single_Step_Exception:
 push 0ffffffffh
 push 1
 jmp Exception
NMI:
 push 0ffffffffh
 push 2
 jmp Exception
Breakpoint_Exception:
 push 0ffffffffh
 push 3
 jmp Exception
Overflow:
 push 0ffffffffh
 push 4
 jmp Exception
Bounds_Check:
 push 0ffffffffh
 push 5
 jmp Exception
Inval_Opcode:
 push 0ffffffffh
 push 6
 jmp Exception
Copr_Not_Available:
 push 0ffffffffh
 push 7
 jmp Exception
Double_Fault:
 push 8
 jmp Exception
Copr_Seg_Overrun:
 push 0ffffffffh
 push 9
 jmp Exception
Inval_TSS:
 push 10
 jmp Exception
Segment_Not_Present:
 push 11
 jmp Exception
Stack_Exception:
 push 12
 jmp Exception
General_Protection:
 push 13
 jmp Exception
Page_Fault:
 push 14
 jmp Exception
Copr_Error:
 push 0ffffffffh
 push 16
 jmp Exception
Exception:
 call Exception_Handler
 add esp,8
 hlt

  我们看到,所有的内中断最终都调用了一个Exception_Handler的函数,这个函数是用C写的,这个函数把传进去的5个参数都打印出来:分别是中断向量号,错误码,发生错误的位置的eip,cs,eflags。

Code:
  1. void Disp_Color_Str(char *p_Str,u32 color);   
  2. void Disp_Int(u32 num);   
  3.   
  4. void Exception_Handler(u32 vec_no,u32 err_code,u32 eip,u32 cs,int eflags)   
  5. {   
  6.     int i;   
  7.        
  8.     Disp_Pos = 0;   
  9.     for(i = 0 ; i < 80 * 5 ; i++)   
  10.     {   
  11.         Disp_Color_Str(" ",0xc);   
  12.     }   
  13.     Disp_Pos = 0;   
  14.        
  15.     Disp_Color_Str("VEC_NO:",0xc);   
  16.     Disp_Int(vec_no);   
  17.     Disp_Color_Str("/n",0xc);   
  18.        
  19.     Disp_Color_Str("ERROR_CODE:",0xc);   
  20.     Disp_Int(err_code);   
  21.     Disp_Color_Str("/n",0xc);   
  22.        
  23.     Disp_Color_Str("CS:",0xc);   
  24.     Disp_Int(cs);   
  25.     Disp_Color_Str("/n",0xc);   
  26.        
  27.     Disp_Color_Str("EIP:",0xc);   
  28.     Disp_Int(eip);   
  29.     Disp_Color_Str("/n",0xc);   
  30.        
  31.     Disp_Color_Str("EFLAGS:",0xc);   
  32.     Disp_Int(eflags);   
  33.     Disp_Color_Str("/n",0xc);   
  34. }  

  这个函数又调用了两个函数,Disp_Color_Str用汇编写的,Disp_Int则用C写的。

;Disp_Color_Str=======================================================
;函数原型:void Disp_Color_Str(char * pszStr,u32 color);
;函数功能:在Disp_Str的基础上改变字符串的颜色
Disp_Color_Str:
 push ebp
 mov ebp,esp
 
 push eax
 push ebx
 push  esi
 push edi
 
 mov esi,[ebp + 8]           ;取得要显示的字符串的偏移
 mov edi,[Disp_Pos]
 xor eax,eax
 mov eax,[ebp + 12]
 shl eax,8
 and eax,0000ff00h           ;ah保存颜色
 
.begin:
 lodsb
 test al,al              ;如果字符为0就退出
 je .exit
 cmp al,0ah              ;如果是回车则跳到改变esi跳到下一行
 jne .disp
 push eax
 mov eax,edi
 mov bl,160
 div bl
 and ax,0ffh
 inc ax
 mov bl,160
 mul bl
 mov edi,eax
 pop eax
 jmp .begin
.disp:
 mov [gs:edi],ax
 add edi,2
 jmp .begin
.exit:
 mov [Disp_Pos],edi          ;全局变量赋回值     
 
 pop edi
 pop esi
 pop ebx
 pop eax
 
 pop ebp

 ret

;end of Disp_Color_Str================================================

Code:
  1. /*======================================================================*  
  2.                                itoa  
  3.  *======================================================================*/  
  4. /* 数字前面的 0 不被显示出来, 比如 0000B800 被显示成 B800 */  
  5. char * itoa(char * str, int num)   
  6. {   
  7.     char *  p = str;   
  8.     char    ch;   
  9.     int i;   
  10.     int flag = 0;   
  11.   
  12.     *p++ = '0';   
  13.     *p++ = 'x';   
  14.   
  15.     if(num == 0){   
  16.         *p++ = '0';   
  17.     }   
  18.     else{      
  19.         for(i=28;i>=0;i-=4){   
  20.             ch = (num >> i) & 0xF;   
  21.             if(flag || (ch > 0)){   
  22.                 flag = 1;   
  23.                 ch += '0';   
  24.                 if(ch > '9'){   
  25.                     ch += 7;   
  26.                 }   
  27.                 *p++ = ch;   
  28.             }   
  29.         }   
  30.     }   
  31.   
  32.     *p = 0;   
  33.   
  34.     return str;   
  35. }   
  36.   
  37. /*======================================================================*  
  38.                                Disp_Int  
  39.  *======================================================================*/  
  40. void Disp_Int(u32 num)   
  41. {   
  42.     char output[16];   
  43.     itoa(output, num);   
  44.     Disp_Color_Str(output,0xc);   
  45. }  

    接下来轮到设置IDT了,先声明两个全局数组分别存放IDT和IDT_PTR。

Code:
  1. Gate IDT[256];   
  2. u8 IDT_Ptr[6];  

    然后是填充1个Gate的函数:Fill_Gate,并在函数Init_IDT中填充16个要处理的内中断的Gate。

Code:

  1. /* 权限 */
    #define PRIVILEGE_KRNL 0
    #define PRIVILEGE_TASK 1
    #define PRIVILEGE_USER 3
  2. /* 中断向量 */
    #define INT_VECTOR_DIVIDE    0x0
    #define INT_VECTOR_DEBUG    0x1
    #define INT_VECTOR_NMI     0x2
    #define INT_VECTOR_BREAKPOINT  0x3
    #define INT_VECTOR_OVERFLOW   0x4
    #define INT_VECTOR_BOUNDS    0x5
    #define INT_VECTOR_INVAL_OP   0x6
    #define INT_VECTOR_COPROC_NOT  0x7
    #define INT_VECTOR_DOUBLE_FAULT 0x8
    #define INT_VECTOR_COPROC_SEG  0x9
    #define INT_VECTOR_INVAL_TSS  0xA
    #define INT_VECTOR_SEG_NOT   0xB
    #define INT_VECTOR_STACK_FAULT 0xC
    #define INT_VECTOR_PROTECTION  0xD
    #define INT_VECTOR_PAGE_FAULT  0xE
    #define INT_VECTOR_COPROC_ERR  0x10
  3. /* 中断处理函数 */  
  4. void    Divide_Error();   
  5. void    Single_Step_Exception();   
  6. void    NMI();   
  7. void    Breakpoint_Exception();   
  8. void    Overflow();   
  9. void    Bounds_Check();   
  10. void    Inval_Opcode();   
  11. void    Copr_Not_Available();   
  12. void    Double_Fault();   
  13. void    Copr_Seg_Overrun();   
  14. void    Inval_TSS();   
  15. void    Segment_Not_Present();   
  16. void    Stack_Exception();   
  17. void    General_Protection();   
  18. void    Page_Fault();   
  19. void    Copr_Error();   
  20.   
  21. void Fill_Gate(u8 idt_no,Int_Handler handler,u8 type,u8 privilege)   
  22. {   
  23.     Gate *p_Gate = (Gate*)&IDT[idt_no];   
  24.     u32 base = (u32)handler;   
  25.     p_Gate->offset_low = base & 0xffff;   
  26.     p_Gate->selector = 16;   
  27.     p_Gate->dcount = 0;   
  28.     p_Gate->attr = type | (privilege << 5);   
  29.     p_Gate->offset_high = (base >> 16) & 0xffff;   
  30. }   
  31.   
  32. void Init_IDT()   
  33. {   
  34.     Fill_Gate(INT_VECTOR_DIVIDE,Divide_Error,DA_386IGate,PRIVILEGE_KRNL);   
  35.     Fill_Gate(INT_VECTOR_DEBUG,Single_Step_Exception,DA_386IGate,PRIVILEGE_KRNL);   
  36.     Fill_Gate(INT_VECTOR_NMI,NMI,DA_386IGate,PRIVILEGE_KRNL);   
  37.     Fill_Gate(INT_VECTOR_BREAKPOINT,Breakpoint_Exception,DA_386IGate,PRIVILEGE_KRNL);   
  38.     Fill_Gate(INT_VECTOR_OVERFLOW,Overflow,DA_386IGate,PRIVILEGE_KRNL);   
  39.     Fill_Gate(INT_VECTOR_BOUNDS,Bounds_Check,DA_386IGate,PRIVILEGE_KRNL);   
  40.     Fill_Gate(INT_VECTOR_INVAL_OP,Inval_Opcode,DA_386IGate,PRIVILEGE_KRNL);   
  41.     Fill_Gate(INT_VECTOR_COPROC_NOT,Copr_Not_Available,DA_386IGate,PRIVILEGE_KRNL);   
  42.     Fill_Gate(INT_VECTOR_DOUBLE_FAULT,Double_Fault,DA_386IGate,PRIVILEGE_KRNL);   
  43.     Fill_Gate(INT_VECTOR_COPROC_SEG,Copr_Seg_Overrun,DA_386IGate,PRIVILEGE_KRNL);   
  44.     Fill_Gate(INT_VECTOR_INVAL_TSS,Inval_TSS,DA_386IGate,PRIVILEGE_KRNL);   
  45.     Fill_Gate(INT_VECTOR_SEG_NOT,Segment_Not_Present,DA_386IGate,PRIVILEGE_KRNL);   
  46.     Fill_Gate(INT_VECTOR_STACK_FAULT,Stack_Exception,DA_386IGate,PRIVILEGE_KRNL);   
  47.     Fill_Gate(INT_VECTOR_PROTECTION,General_Protection,DA_386IGate,PRIVILEGE_KRNL);   
  48.     Fill_Gate(INT_VECTOR_PAGE_FAULT,Page_Fault,DA_386IGate,PRIVILEGE_KRNL);   
  49.     Fill_Gate(INT_VECTOR_COPROC_ERR,Copr_Error,DA_386IGate,PRIVILEGE_KRNL);   
  50. }  

    接着在C_Start中添加填充IDT_Ptr的代码。

Code:
  1. Init_IDT();   
  2. *(u16*)(&IDT_Ptr[0]) = sizeof(Gate) * 256 - 1;   
  3. *(u32*)(&IDT_Ptr[2]) = (u32)&IDT;     

    最后在kernel.asm里添加lidt  [IDT_Ptr]来加载IDTR,并初始化各段寄存器使用新填充好的GDT,并进行跳转实验跳到_test标号处执行,jmp  100:0故意写的错误的语句,我们只在GDT中填充了4个描述符,这样跳显然越界了,产生一个General Protection异常,在屏幕打印相应的出错信息。

    明天再继续弄外中断吧,呵呵。附上源代码:

    kernel.asm:

extern GDT_Ptr
extern IDT_Ptr
extern Disp_Pos
extern C_Start
extern Exception_Handler

Selector_Loader_Flat_RW  equ  8

Selector_Kernel_Flat_RW   equ   8
Selector_Kernel_Flat_C  equ  16
Selector_Kernel_Video   equ  24

[section .bss]

Stack_Space resb 2 * 1024
Top_Of_Stack:

[section .text]

global Divide_Error
global Single_Step_Exception
global NMI
global Breakpoint_Exception
global Overflow
global Bounds_Check
global Inval_Opcode
global Copr_Not_Available
global Double_Fault
global Copr_Seg_Overrun
global Inval_TSS
global Segment_Not_Present
global Stack_Exception
global General_Protection
global Page_Fault
global Copr_Error

global Out_Byte
global Disp_Color_Str

global _start

_start:
 mov ax,Selector_Loader_Flat_RW
 mov ds,ax
 mov es,ax
 
 call C_Start
 
 lgdt [GDT_Ptr]
 lidt [IDT_Ptr]
 
 mov ax,Selector_Kernel_Flat_RW
 mov ds,ax
 mov es,ax
 mov ss,ax
 mov esp,Top_Of_Stack 
 mov ax,Selector_Kernel_Video
 mov gs,ax
 
 jmp Selector_Kernel_Flat_C:_test
 
_test:
 jmp 100:0
 hlt

Out_Byte:
 push ebp
 mov ebp,esp
 
 push eax
 push edx
 
 mov edx,[ebp + 8]
 mov eax,[ebp + 12]
 
 out dx,al
 
 pop edx
 pop eax
 
 pop ebp

 ret
 
;Disp_Color_Str=======================================================
;函数原型:void Disp_Color_Str(char * pszStr,u32 color);
;函数功能:在Disp_Str的基础上改变字符串的颜色
Disp_Color_Str:
 push ebp
 mov ebp,esp
 
 push eax
 push ebx
 push  esi
 push edi
 
 mov esi,[ebp + 8]           ;取得要显示的字符串的偏移
 mov edi,[Disp_Pos]
 xor eax,eax
 mov eax,[ebp + 12]
 shl eax,8
 and eax,0000ff00h           ;ah保存颜色
 
.begin:
 lodsb
 test al,al              ;如果字符为0就退出
 je .exit
 cmp al,0ah              ;如果是回车则跳到改变esi跳到下一行
 jne .disp
 push eax
 mov eax,edi
 mov bl,160
 div bl
 and ax,0ffh
 inc ax
 mov bl,160
 mul bl
 mov edi,eax
 pop eax
 jmp .begin
.disp:
 mov [gs:edi],ax
 add edi,2
 jmp .begin
.exit:
 mov [Disp_Pos],edi          ;全局变量赋回值     
 
 pop edi
 pop esi
 pop ebx
 pop eax
 
 pop ebp

 ret

;end of Disp_Color_Str================================================
 
Divide_Error:
 push 0ffffffffh
 push 0
 jmp Exception
Single_Step_Exception:
 push 0ffffffffh
 push 1
 jmp Exception
NMI:
 push 0ffffffffh
 push 2
 jmp Exception
Breakpoint_Exception:
 push 0ffffffffh
 push 3
 jmp Exception
Overflow:
 push 0ffffffffh
 push 4
 jmp Exception
Bounds_Check:
 push 0ffffffffh
 push 5
 jmp Exception
Inval_Opcode:
 push 0ffffffffh
 push 6
 jmp Exception
Copr_Not_Available:
 push 0ffffffffh
 push 7
 jmp Exception
Double_Fault:
 push 8
 jmp Exception
Copr_Seg_Overrun:
 push 0ffffffffh
 push 9
 jmp Exception
Inval_TSS:
 push 10
 jmp Exception
Segment_Not_Present:
 push 11
 jmp Exception
Stack_Exception:
 push 12
 jmp Exception
General_Protection:
 push 13
 jmp Exception
Page_Fault:
 push 14
 jmp Exception
Copr_Error:
 push 0ffffffffh
 push 16
 jmp Exception
Exception:
 call Exception_Handler
 add esp,8
 hlt

 

start.c

Code:
  1. typedef unsigned char  u8;       
  2. typedef unsigned short u16;      
  3. typedef unsigned int   u32;       
  4.       
  5. /* 描述符类型值说明 */      
  6. #define DA_32               0x4000              /* 32 位段              */         
  7. #define DA_LIMIT_4K         0x8000              /* 段界限粒度为 4K 字节   */       
  8. #define DA_DPL0             0x00                /* DPL = 0              */       
  9. #define DA_DPL1             0x20                /* DPL = 1              */       
  10. #define DA_DPL2             0x40                /* DPL = 2              */       
  11. #define DA_DPL3             0x60                /* DPL = 3              */       
  12.            
  13. /* 存储段描述符类型值说明 */      
  14. #define DA_DR               0x90                /* 存在的只读数据段类型值          */       
  15. #define DA_DRW              0x92                /* 存在的可读写数据段属性值        */       
  16. #define DA_DRWA             0x93                /* 存在的已访问可读写数据段类型值   */       
  17. #define DA_C                0x98                /* 存在的只执行代码段属性值        */       
  18. #define DA_CR               0x9A                /* 存在的可执行可读代码段属性值     */       
  19. #define DA_CCO              0x9C                /* 存在的只执行一致代码段属性值     */       
  20. #define DA_CCOR             0x9E                /* 存在的可执行可读一致代码段属性值 */       
  21.            
  22. /* 系统段描述符类型值说明 */      
  23. #define DA_LDT              0x82                /* 局部描述符表段类型值           */       
  24. #define DA_TaskGate         0x85                /* 任务门类型值                  */        
  25. #define DA_386TSS           0x89                /* 可用 386 任务状态段类型值      */       
  26. #define DA_386CGate         0x8C                /* 386 调用门类型值              */       
  27. #define DA_386IGate         0x8E                /* 386 中断门类型值              */       
  28. #define DA_386TGate         0x8F                /* 386 陷阱门类型值              */       
  29.   
  30.   
  31. /* 权限 */  
  32. #define PRIVILEGE_KRNL  0   
  33. #define PRIVILEGE_TASK  1   
  34. #define PRIVILEGE_USER  3   
  35.   
  36. /* 中断向量 */  
  37. #define INT_VECTOR_DIVIDE               0x0   
  38. #define INT_VECTOR_DEBUG                0x1   
  39. #define INT_VECTOR_NMI                  0x2   
  40. #define INT_VECTOR_BREAKPOINT       0x3   
  41. #define INT_VECTOR_OVERFLOW         0x4   
  42. #define INT_VECTOR_BOUNDS               0x5   
  43. #define INT_VECTOR_INVAL_OP         0x6   
  44. #define INT_VECTOR_COPROC_NOT       0x7   
  45. #define INT_VECTOR_DOUBLE_FAULT 0x8   
  46. #define INT_VECTOR_COPROC_SEG       0x9   
  47. #define INT_VECTOR_INVAL_TSS        0xA   
  48. #define INT_VECTOR_SEG_NOT          0xB   
  49. #define INT_VECTOR_STACK_FAULT  0xC   
  50. #define INT_VECTOR_PROTECTION       0xD   
  51. #define INT_VECTOR_PAGE_FAULT       0xE   
  52. #define INT_VECTOR_COPROC_ERR       0x10   
  53.   
  54. /* 中断处理函数 */  
  55. void    Divide_Error();   
  56. void    Single_Step_Exception();   
  57. void    NMI();   
  58. void    Breakpoint_Exception();   
  59. void    Overflow();   
  60. void    Bounds_Check();   
  61. void    Inval_Opcode();   
  62. void    Copr_Not_Available();   
  63. void    Double_Fault();   
  64. void    Copr_Seg_Overrun();   
  65. void    Inval_TSS();   
  66. void    Segment_Not_Present();   
  67. void    Stack_Exception();   
  68. void    General_Protection();   
  69. void    Page_Fault();   
  70. void    Copr_Error();   
  71.       
  72. typedef struct s_descriptor       
  73. {       
  74.     u16 limit_low;                      /* limit(0..15) */      
  75.     u16 base_low;                       /* base(0..15) */      
  76.     u8  base_mid;                       /* base(16..23) */      
  77.     u8  attr1;                          /* P(1) DPL(2) S(1) TYPE(4)*/      
  78.     u8  limit_high_attr2;               /* G(1) D/B(1) O(1) AVL(1) limit(16..19) */      
  79.     u8  base_high;                      /* base(24..31) */      
  80. }Descriptor;       
  81.   
  82. typedef struct s_gate   
  83. {   
  84.     u16 offset_low;                     /* offset(0..15) */  
  85.     u16 selector;                           /* selector */  
  86.     u8  dcount;    
  87.     u8  attr;                                   /* P(1) DPL(2) S(1) TYPE(4) */  
  88.     u16 offset_high;                    /* offset(16..31) */                                                       
  89. }Gate;   
  90.       
  91. Descriptor GDT[128];       
  92. u8 GDT_Ptr[6];       
  93. Gate IDT[256];   
  94. u8 IDT_Ptr[6];   
  95. u32 Disp_Pos = 0;   
  96.   
  97. typedef void (*Int_Handler)();   
  98.   
  99. void Disp_Color_Str(char *p_Str,u32 color);   
  100. void Disp_Int(u32 num);   
  101. void Out_Byte(u16 port,u8 value);   
  102.       
  103. void Fill_Desc(u8 desc_no,u32 base,u32 limit,u16 attr)       
  104. {       
  105.     Descriptor *p_Desc = (Descriptor *)&GDT[desc_no];       
  106.     p_Desc->limit_low = limit & 0xffff;       
  107.     p_Desc->base_low = base & 0xffff;       
  108.     p_Desc->base_mid = (base >> 16) & 0xff;       
  109.     p_Desc->attr1 = attr & 0xff;       
  110.     p_Desc->limit_high_attr2 = ((limit >> 16) & 0xf) | (attr >> 8);       
  111.     p_Desc->base_high = (base >> 24) & 0xff;       
  112. }       
  113.       
  114. void Init_GDT()       
  115. {       
  116.     Fill_Desc(0,0,0,0);       
  117.     Fill_Desc(1,0,0xfffff,DA_DRW | DA_32 | DA_LIMIT_4K);       
  118.     Fill_Desc(2,0,0xfffff,DA_C | DA_32 | DA_LIMIT_4K);       
  119.     Fill_Desc(3,0xb8000,0xffff,DA_DRW);       
  120. }       
  121.   
  122. void Fill_Gate(u8 idt_no,Int_Handler handler,u8 type,u8 privilege)   
  123. {   
  124.     Gate *p_Gate = (Gate*)&IDT[idt_no];   
  125.     u32 base = (u32)handler;   
  126.     p_Gate->offset_low = base & 0xffff;   
  127.     p_Gate->selector = 16;   
  128.     p_Gate->dcount = 0;   
  129.     p_Gate->attr = type | (privilege << 5);   
  130.     p_Gate->offset_high = (base >> 16) & 0xffff;   
  131. }   
  132.   
  133. void Init_IDT()   
  134. {   
  135.     Fill_Gate(INT_VECTOR_DIVIDE,Divide_Error,DA_386IGate,PRIVILEGE_KRNL);   
  136.     Fill_Gate(INT_VECTOR_DEBUG,Single_Step_Exception,DA_386IGate,PRIVILEGE_KRNL);   
  137.     Fill_Gate(INT_VECTOR_NMI,NMI,DA_386IGate,PRIVILEGE_KRNL);   
  138.     Fill_Gate(INT_VECTOR_BREAKPOINT,Breakpoint_Exception,DA_386IGate,PRIVILEGE_KRNL);   
  139.     Fill_Gate(INT_VECTOR_OVERFLOW,Overflow,DA_386IGate,PRIVILEGE_KRNL);   
  140.     Fill_Gate(INT_VECTOR_BOUNDS,Bounds_Check,DA_386IGate,PRIVILEGE_KRNL);   
  141.     Fill_Gate(INT_VECTOR_INVAL_OP,Inval_Opcode,DA_386IGate,PRIVILEGE_KRNL);   
  142.     Fill_Gate(INT_VECTOR_COPROC_NOT,Copr_Not_Available,DA_386IGate,PRIVILEGE_KRNL);   
  143.     Fill_Gate(INT_VECTOR_DOUBLE_FAULT,Double_Fault,DA_386IGate,PRIVILEGE_KRNL);   
  144.     Fill_Gate(INT_VECTOR_COPROC_SEG,Copr_Seg_Overrun,DA_386IGate,PRIVILEGE_KRNL);   
  145.     Fill_Gate(INT_VECTOR_INVAL_TSS,Inval_TSS,DA_386IGate,PRIVILEGE_KRNL);   
  146.     Fill_Gate(INT_VECTOR_SEG_NOT,Segment_Not_Present,DA_386IGate,PRIVILEGE_KRNL);   
  147.     Fill_Gate(INT_VECTOR_STACK_FAULT,Stack_Exception,DA_386IGate,PRIVILEGE_KRNL);   
  148.     Fill_Gate(INT_VECTOR_PROTECTION,General_Protection,DA_386IGate,PRIVILEGE_KRNL);   
  149.     Fill_Gate(INT_VECTOR_PAGE_FAULT,Page_Fault,DA_386IGate,PRIVILEGE_KRNL);   
  150.     Fill_Gate(INT_VECTOR_COPROC_ERR,Copr_Error,DA_386IGate,PRIVILEGE_KRNL);   
  151. }   
  152.   
  153. void Init_8259A()   
  154. {   
  155.     Out_Byte(0x20,0x11);   
  156.     Out_Byte(0xa0,0x11);   
  157.        
  158.     Out_Byte(0x21,0x20);   
  159.     Out_Byte(0xa1,0x28);   
  160.        
  161.     Out_Byte(0x21,0x4);   
  162.     Out_Byte(0xa1,0x2);   
  163.        
  164.     Out_Byte(0x21,0x1);   
  165.     Out_Byte(0xa1,0x1);   
  166.        
  167.     Out_Byte(0x21,0xff);   
  168.     Out_Byte(0xa1,0xff);   
  169. }   
  170.       
  171. void C_Start()       
  172. {       
  173.         Init_8259A();   
  174.     Init_GDT();       
  175.     Init_IDT();   
  176.     *(u16*)(&GDT_Ptr[0]) = 4 * 8 - 1;       
  177.     *(u32*)(&GDT_Ptr[2]) = (u32)&GDT;    
  178.     *(u16*)(&IDT_Ptr[0]) = sizeof(Gate) * 256 - 1;   
  179.         *(u32*)(&IDT_Ptr[2]) = (u32)&IDT;      
  180. }      
  181.   
  182. void Exception_Handler(u32 vec_no,u32 err_code,u32 eip,u32 cs,int eflags)   
  183. {   
  184.     int i;   
  185.        
  186.     Disp_Pos = 0;   
  187.     for(i = 0 ; i < 80 * 5 ; i++)   
  188.     {   
  189.         Disp_Color_Str(" ",0xc);   
  190.     }   
  191.     Disp_Pos = 0;   
  192.        
  193.     Disp_Color_Str("VEC_NO:",0xc);   
  194.     Disp_Int(vec_no);   
  195.     Disp_Color_Str("/n",0xc);   
  196.        
  197.     Disp_Color_Str("ERROR_CODE:",0xc);   
  198.     Disp_Int(err_code);   
  199.     Disp_Color_Str("/n",0xc);   
  200.        
  201.     Disp_Color_Str("CS:",0xc);   
  202.     Disp_Int(cs);   
  203.     Disp_Color_Str("/n",0xc);   
  204.        
  205.     Disp_Color_Str("EIP:",0xc);   
  206.     Disp_Int(eip);   
  207.     Disp_Color_Str("/n",0xc);   
  208.        
  209.     Disp_Color_Str("EFLAGS:",0xc);   
  210.     Disp_Int(eflags);   
  211.     Disp_Color_Str("/n",0xc);   
  212. }   
  213.   
  214. /*======================================================================*  
  215.                                itoa  
  216.  *======================================================================*/  
  217. /* 数字前面的 0 不被显示出来, 比如 0000B800 被显示成 B800 */  
  218. char * itoa(char * str, int num)   
  219. {   
  220.     char *  p = str;   
  221.     char    ch;   
  222.     int i;   
  223.     int flag = 0;   
  224.   
  225.     *p++ = '0';   
  226.     *p++ = 'x';   
  227.   
  228.     if(num == 0){   
  229.         *p++ = '0';   
  230.     }   
  231.     else{      
  232.         for(i=28;i>=0;i-=4){   
  233.             ch = (num >> i) & 0xF;   
  234.             if(flag || (ch > 0)){   
  235.                 flag = 1;   
  236.                 ch += '0';   
  237.                 if(ch > '9'){   
  238.                     ch += 7;   
  239.                 }   
  240.                 *p++ = ch;   
  241.             }   
  242.         }   
  243.     }   
  244.   
  245.     *p = 0;   
  246.   
  247.     return str;   
  248. }   
  249.   
  250. /*======================================================================*  
  251.                                Disp_Int  
  252.  *======================================================================*/  
  253. void Disp_Int(u32 num)   
  254. {   
  255.     char output[16];   
  256.     itoa(output, num);   
  257.     Disp_Color_Str(output,0xc);   
  258. }  

     最后照例附图一张:

   

你可能感兴趣的:(第五章相应的汇编转换成C的分析【二】)