386-2.txt
上传用户:gb3576
上传日期:2007-01-03
资源大小:24k
文件大小:6k
源码类别:

Shell编程

开发平台:

DOS

  1.                                                   ┌┐┌┐∞
  2. 【 80386保护模式简介二 】                    ┘└┘└┘
  3. --------------------------------------------------------------------------
  4.     进入保护模式可以得到很多好处 ,让你的程式不再有 640K 限制 ,可以产生虚
  5. 拟记忆体、拦 I/O ,所有的应用程式读写系统暂存器 ,产生中断....都可以完全拦
  6. 截 ,而且 TSS 工作切换能力可以让你不占用 DOS 下的堆叠区 ,还有很多好处无法
  7. 一一叙述 ,因此由笔者来教你如何切入保护模式吧....从简单的开始。
  8.  
  9.     在保护模式下有很多新的名词 ,包含 GDT.LDT.IDT 以及 CR0-CR3 ,笔者对保护
  10. 模式并不清楚 ,所以底下资料可能有错误。这里使用大量的线性记忆体观念 ,请您
  11. 一定要从头往後看 ,否则很可能會看不懂 ,且必须懂线性记忆体计算方式。
  12.  
  13. --------------------------------------------------------------------------
  14.     在进入保护模式时 ,首先你要先设定 GDT 表格 ,这个表格描述主要是来定义每
  15. 个段落的记忆体起始位址与长度、存取权。   这个情形就好像传统 REAL MODE  那
  16. 样 ,REAL MODE 每个区段的记忆体开始位址与长度都已经由 CPU 定死了 ,比如说当
  17. 我们看到 1000:0000 ,其实它就是指记忆体的第 64K 位址 ,同理看到 2000:0000
  18. 就代表是第 128K 位址 ,定址方式就是 Segment:Offset。
  19.  
  20.     而保护模式的段落起始位址与长度却是可程式变动的 ,这个可变动的段落起始
  21. 位址与长度就是由 GDT 来设定的 ,根據这个值 ,你可以将每个段落改成64K ,或是
  22. 1MB...甚至更多 ,可任意设定 1BYTE ̄4GB ,所以定址方式变成 Selector:Offset
  23. 或许您曾用过 386DEBUG ,看过定址方式为 XXXX:XXXXXXXX ,根據後面这八位数 ,
  24. 理论上可定址到 4GB ,其实这是不行的 ,如果你在 GDT 表格设定的记忆体为 1K
  25. 则你尝试 DUMP 1K 以後的记忆体都會看到 FF ,就好像没有记忆体一般。
  26.  
  27. ---------------------------------------------------------------------------
  28. Gdtadds dw      0018h,GdtTable 32 位元线性位址
  29. GdtTable db     00h,00h,00h,00h,00h,00h,00h,00h         ;
  30.         db      7fh,ffh,00h,08h,0bh,93h,00h,00h         ;B800:0 32K
  31.         db      ffh,ffh,56h,34h,12h,93h,0fh,78h         ;
  32.                 ^^^^^^^ ^^^^^^^^^^^ ^^^ ^^^ ^^^
  33.                 ↑      ↑          ↑  ↑  ↑
  34.                 │      │          └──────93=可读写区段
  35.                 │      │              │  │
  36.                 └───────────┴────0fffff+1=1MB (Limits)
  37.                         │                  │
  38.                         └─────────┴──12345678 (Base)
  39.  
  40.  
  41. 它所代表的意思是如下图所示:(每组 8 byte)
  42.  
  43.         ┌──────────────────────┐
  44.        1│                Limit bit 0-15              │ 0 byte
  45.         ├──────────────────────┤
  46.        3│                Base bit 0-15               │ 2
  47.         ├──────────┬───────────┤
  48.        5│       存取权       │    Base bit 16-23    │ 4
  49.         ├──────────┼───────────┤
  50.        7│   Base bit 24-31   │G│..│limit bit 16-19│ 6
  51.         └──────────┴───────────┘
  52.             "G"代表 Limit 的单位是 Byte 或 PAGE(4K)
  53.  
  54. 所以....
  55.  
  56. #0000  Segment not present.
  57. #0008  Base=000B8000  Limit=0000FFFF  Flags=93  USE32  Byte granularity
  58. #0010  Base=12345678  Limit=000FFFFF  Flags=93  USE32  Byte granularity
  59. ^^^^^Selector                               ^^存取权
  60.  
  61.  
  62.  
  63. 设定完後 ,就是切入保护模式 ,只要将 CR0 暂存器的 Bit0 设为 '1' ,再用一个
  64. 跳越指令 ,就进入保护模式了。
  65.  
  66.  
  67. ---------------------------------------------------------------------------
  68. 讲不懂没关系 ,现在来看看实例 ,这样比较容易懂..
  69.  
  70. C:>386MICE SAMPLE.EXE
  71. -G 1AE
  72. EAX=00044A1C  EBX=00000003  ECX=00000000  EDX=00000100
  73. ESI=00000000  EDI=00000000  EBP=00000000  ESP=0000FFFE
  74. DS=4A1C  SS=4A1C  ES=4A1C  FS=4A0C  GS=4A0C
  75. -U 1AE
  76. 4A1C:000001AE           CLI
  77. 4A1C:000001AF           LGDT    CS:[BX]     ──→ DUMP CS:[BX] ──→ 
  78. 4A1C:00000003  18 00 C9 A1 04 00 <--- GDT 表放在 0004A1C9 长度 18h
  79. 4A1C:000001B3           MOV     
  80. EAX,CR0                                                        │
  81. 4A1C:000001B6           OR      
  82. EAX,1                                                          ↓
  83. 4A1C:000001BA           MOV     CR0,EAX                                
  84. 4A1C:00000009  00 00 00 00 00 00 00 00-FF FF C0 A1 04 9B 00-00
  85. 4A1C:000001BD           JMP     01C0                                   
  86. 4A1C:00000010  FF FF 00 80 0B 93 00 00 (GDT表)
  87. 4A1C:000001BF           NOP
  88. 4A1C:000001C0           MOV     AX,0008H
  89. 4A1C:000001C3           MOV     DS,AX
  90. 4A1C:000001C5           MOV     WORD PTR DS:[0000H],7041h
  91.  
  92.  
  93. 由上面的 GDT 表知道 此程式共规划了三个区段 ,其中 0000 区段是不使用
  94. 故区段的表示方式如下:
  95.  
  96. #0000  Segment not present.
  97. #0008  Base=0004A1C0  Limit=0000FFFF  Flags=9B  USE32  Byte granularity
  98. #0010  Base=000B8000  Limit=0000FFFF  Flags=93  USE32  Byte granularity
  99.  
  100.  
  101.  
  102. -G 1BD
  103. EAX=00000001  EBX=00000003  ECX=00000000  EDX=00000100
  104. ESI=00000000  EDI=00000000  EBP=00000000  ESP=0000FFFE
  105. DS=4A1C  SS=4A1C  ES=4A1C  FS=4A0C  GS=4A0C
  106. 4A1C:000001BD           JMP     01C0
  107.  
  108. -T (这儿就算是进入保护模式了)
  109. EAX=00000001  EBX=00000003  ECX=00000000  EDX=00000100
  110. ESI=00000000  EDI=00000000  EBP=00000000  ESP=0000FFFE
  111. DS=0000  SS=0000  ES=0000  FS=0000  GS=0000
  112. 0000:000001C0           MOV     AX,0008H
  113. 0000:000001C3           MOV     DS,AX
  114. 0000:000001C5           MOV     WORD PTR DS:[0000H],7041h
  115.  
  116.  
  117.  
  118. 因为进入保护模式 ,所以 Selector 的区段应该要去查 GDT 表格 ,这个例
  119. 子的 Selector 0010 的 Base = B8000 ,所以...
  120. 保护模式下的 0010:00000000 = 真实模式下的 B800:0000 ,这样您懂了吗?
  121.  
  122. 在行号 1C5 的位址有一行写入 7041 的动作 ,就是在萤幕秀 'A' 反白字元.
  123.  
  124. 最後要进入真实模式时 ,只要将 CR0 的 Bit0 设为 '0' ,再用一个跳越指
  125. 令就回到真实模式了..
  126.  
  127. --------------------------------------------------------------------------
  128. 後记:
  129.     若有问题 ,烦在本站『站内信箱』留信给我....尽量避免使用网路信 ,
  130. 且尽快提出 ,否则接下来的课程将會更难懂 ,如果你是完全不懂 ,麻烦也留
  131. 信给我 ,我會再把这一章节再细细重新说明。至於对组合语言不懂 ,或是对
  132. 保护模式没兴趣的人 ,本人就帮不上忙了。
  133.  
  134.     A:下一次笔者将继续解说 V86 模式下的工作切换
  135.     B:等级权限 / 拦 I/O
  136.  
  137. ┌───────────────────────────────────┐
  138. │  Soft Bugger 软体蛀虫 90:90/2                    软体新技术的实行者  │
  139. │  BBS:02-5955461 24HR          ID:Werong Ho               -- 软蛀 --  │
  140. └───────────────────────────────────┘
  141.