Test

 

 1232605195

youngray 标签: 程序代码如下

  1: %include "pm.inc"
  2: 
  3: org 0100h
  4:     jmp LABEL_BEGIN
  5: 
  6: [section .gdt]
  7: GDT_BEGIN:            ;空描述符,Intel规定必须要有该描述符
  8:     Descriptor    0,            0,                    0
  9: GDT_NORMAL:         ;Normal描述符,从保护模式返回实模式时,用到该描述符
 10:     Descriptor    0,            0ffffh,                DA_DRW
 11: GDT_CODE16:            ;该描述符指向保护模式下的16位代码段
 12:     Descriptor    0,            0ffffh,                DA_C
 13: GDT_CODE32:            ;该描述符指向保护模式下的32位代码段
 14:     Descriptor    0,            SegCode32Len - 1,    DA_C + DA_32
 15: GDT_DATA:            ;该描述指向保护模式下要用到的数据段
 16:     Descriptor    0,            SegDataLen - 1,        DA_DRW
 17: GDT_STACK:            ;该描述符指向保护模式下要用到的堆栈段
 18:     Descriptor    0,            TopOfStack,            DA_DRWA + DA_32
 19: GDT_TEST:            ;该描述符指向测试字符串的物理地址
 20:     Descriptor    0500000h,    0ffffh,                DA_DRW
 21: GDT_VIDEO:            ;该描述符指向显存首地址
 22:     Descriptor    0b8000h,    0ffffh,                DA_DRW
 23: 
 24: Gdt_Len            equ            $ - GDT_BEGIN
 25: GdtPtr            dw            Gdt_Len - 1
 26:                 dd            0    ;这里的0起到保留内存空间的作用,不做为实际值
 27: 
 28: ; 定义 GDT 选择子
 29: SelectorNormal    equ            GDT_NORMAL - GDT_BEGIN
 30: SelectorCode16    equ            GDT_CODE16 - GDT_BEGIN
 31: SelectorCode32    equ            GDT_CODE32 - GDT_BEGIN
 32: SelectorData    equ            GDT_DATA   - GDT_BEGIN
 33: SelectorStack    equ            GDT_STACK  - GDT_BEGIN
 34: SelectorTest    equ            GDT_TEST   - GDT_BEGIN
 35: SelectorVideo    equ            GDT_VIDEO  - GDT_BEGIN
 36: 
 37: [section .data1]     ;保护模式下要用到的数据段
 38: align 32
 39: [bits 32]
 40: LABEL_DATA:
 41: SPValueInReal    dw    0   ;该变量保存实模式下sp指针的值
 42: PMMessage        db    "In Protect Mode now. ^-^", 0   ;在保护模式中显示
 43: PMMessageOffset equ    PMMessage - $$  
 44: TestStr            db  "ABCDEFGH", 0    ;测试字符串
 45: TestStrOffset    equ    TestStr - $$
 46: SegDataLen        equ    $ - LABEL_DATA
 47: 
 48: [section .gs]       ;保护模式下要用到的全局堆栈段
 49: align 32
 50: [bits 32]
 51: LABEL_STACK:
 52:     times 512 db 0
 53: TopOfStack         equ    $ - LABEL_STACK - 1
 54: 
 55: [section  .s16]
 56: [bits        16]
 57: LABEL_BEGIN:        ;程序从这里开始执行
 58:     mov ax, cs
 59:     mov ds, ax
 60:     mov es, ax
 61:     mov ss, ax
 62:     mov sp, 0100h
 63: 
 64:     ;保存实模式下cs段寄存器的值到LABEL_GO_BACK_TO_REAL + 3所指向的地址处
 65:     mov [LABEL_GO_BACK_TO_REAL+3], ax 
 66:     mov [SPValueInReal], sp    ;保存实模式下sp指针的值到SPValueInReal变量
 67: 
 68:     ;初始化16位代码段描述符GDT_CODE16的基址值
 69:     xor eax, eax
 70:     mov ax , cs           ;将cs段寄存器的值传送到ax
 71:     shl eax, 4            ;将ax中段地址左移位
 72:     add ax , LABEL_CODE16 ;将LABEL_CODE16的偏移地址加到ax,得到它的物理地址
 73:     mov [GDT_CODE16 + 2], ax  ;将该物理地址分三部分分别放入描述符GDT_CODE16
 74:     shr eax, 16                  ;中,具体的放置位置已经由Intel规定好了,你只须
 75:     mov [GDT_CODE16 + 4], al  ;按照GDT描述符的规定把相应位置的值放进去即可
 76:     mov [GDT_CODE16 + 7], ah  ;此时,GDT_CODE16的基址值初始化完毕
 77: 
 78:     ;初始化32位代码段描述符GDT_CODE32的基址值
 79:     xor eax, eax
 80:     mov ax , cs
 81:     shl eax, 4
 82:     add ax, LABEL_CODE32
 83:     mov [GDT_CODE32 + 2], ax
 84:     shr eax, 16
 85:     mov [GDT_CODE32 + 4], al
 86:     mov [GDT_CODE32 + 7], ah
 87: 
 88:     ;初始化数据段描述符GDT_DATA的基址值
 89:     xor eax, eax
 90:     mov ax , ds    ;ds的值在上面的代码被置为cs的值
 91:     shl eax, 4
 92:     add eax, LABEL_DATA
 93:     mov [GDT_DATA + 2], ax
 94:     shr eax, 16
 95:     mov [GDT_DATA + 4], al
 96:     mov [GDT_DATA + 7], ah
 97: 
 98:     ;初始化堆栈段描述符GDT_STACK的基址值
 99:     xor eax, eax
100:     mov ax , ds
101:     shl eax, 4
102:     add eax, LABEL_STACK
103:     mov [GDT_STACK + 2], ax
104:     shr eax, 16
105:     mov [GDT_STACK + 4], al
106:     mov [GDT_STACK + 7], ah
107: 
108:     ;为加载 GDTR 作准备
109:     xor eax, eax
110:     mov ax , ds
111:     shl eax, 4
112:     add eax, GDT_BEGIN
113:     mov [GdtPtr + 2], eax
114: 
115:     ;加载 GDTR
116:     lgdt [GdtPtr]
117: 
118:     ;关中断
119:     cli
120:     ;打开A20地址线
121:     in  al, 92h
122:     or  al, 00000010b
123:     out 92h, al
124:     ;打开进入保护模式的开关,该开关位于cr0寄存器的第0位
125:     mov eax, cr0
126:     or  eax, 1
127:     mov cr0, eax
128: 
129:     ;真正进入保护模式
130:     jmp dword SelectorCode32:0   ;为了防止发生地址截断,这里的dword必不可少
131: 
132: LABEL_REAL_ENTRY:        ;从保护模式跳回实模式就到了这里
133:     mov ax, cs
134:     mov ds, ax
135:     mov es, ax
136:     mov ss, ax
137:     mov sp, [SPValueInReal]
138: 
139:     ;关闭A20地址线
140:     in  al, 92h
141:     and al, 11111101b
142:     out 92h, al
143:     ;开中断
144:     sti
145: 
146:     ;返回 DOS
147:     mov ax, 4c00h
148:     int 21h

 

  1: #include <stdio.h>
  2: int main()
  3: {
  4: printf("NOT helloWorld~/n");
  5: return 0
  6: }

 

   1:  #include <stdio.h>
   2:  int main()
   3:  {
   4:  printf("NOT helloWorld~/n");
   5:  return 0
   6:  }
  1: #include <stdio.h>
  2: int main()
  3: {
  4: printf("NOT helloWorld~/n");
  5: return 0
  6: }

转载请注明出处:http://blog.youkuaiyun.com/whyiug1/archive/2011/03/07/6229496.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值