小试保护模式

前几天将段式保护模式从理论上了解了。所以这几天就借助一些书籍和网络得力量来争取实践---将代码跳入保护模式。
首先了解跳入保护模式的基本步骤
1、将代码段基址存入GDT
2、利用lgdt将GDT基址以及长度加载到gdtr寄存器
3、关中断
4、打开20号地址线
5、置位CR0的PE,准备切换
6、跳入保护模式下的代码段

下面就是这个简单跳跃得代码:
pm.inc包含一些宏定义以及段的属性定义值

%macro Descriptor 3
dw %2 & 0ffffh
dw %1 & 0ffffh
db (%1>>16) & 0ffh
dw ((%2>>8)&0f00h)|(%3 & 0f0ffh)
db (%2>>24)&0ffh
%endmacro

DA_32 equ 4000h ;32位段

DA_DPL0 equ 00h ;DPL=0
DA_DPL1 equ 220h ;DPL=1
DA_DPL2 equ 40h ;DPL=2
DA_DPL3 equ 60h ;DPL=3

DA_DR equ 90h ;只读数据段
DA_DRW equ 92h ;可读可写数据段
DA_DRWA equ 93h ;可读可写已访问数据段
DA_C equ 98h ;只执行代码段
DA_CR equ 9ah ;可读可执行代码段
DA_CCO equ 9ch ;非一致可执行代码段
DA_CCRO equ 9eh ;可读非一致可执行代码段



protec.asm这是主要逻辑部分。功能实现得主体

%include "pm.inc"

org 07c00h
jmp START

[SECTION .gdt]
GDT_DEC: Descriptor 0, 0, 0
CODE32_DEC: Descriptor 0,Code32Len-1,DA_32 + DA_CR
VIDEO_DEC: Descriptor 0b8000h,0ffffh ,DA_DRW

GdtLen equ $ - GDT_DEC
Gdtptr dw GdtLen - 1
dd 0

SelectorCode32 equ CODE32_DEC - GDT_DEC
SelectorVideo equ VIDEO_DEC - GDT_DEC

[SECTION .s16]
[BITS 16]
START:
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0100h
;加载代码段基址到GDT描述符
xor eax,eax
mov ax,cs
shl eax,4
add eax,CODE32_SEG
mov word [CODE32_DEC+2],ax
shr eax,16
mov byte [CODE32_DEC+4],al
mov byte [CODE32_DEC+7],ah
;加载GDT基址及长度到gdtr
xor eax,eax
mov ax,ds
shl eax,4
add eax,GDT_DEC
mov dword [Gdtptr+2],eax

lgdt [Gdtptr]
;关中断
cli
;打开A20
in al,92h
or al,02h
out 92h,al
;置位PE
mov eax,cr0
or eax,01h
mov cr0,eax
;跳转保护模式
jmp dword SelectorCode32:0
[SECTION .s32]
[BITS 32]
CODE32_SEG:
mov ax,SelectorVideo
mov gs,ax
mov esi,offMessage
mov edi,(80*12+30)*2
mov ah,0ch
cld
call DesplayMessage
Message: db "Welcome protected place",0
offMessage equ Message - $$
DesplayMessage:
.2:
mov al,[cs:esi]
test al,al
.1:
jz .1
mov [gs:edi],ax
add edi,2
inc esi
jmp .2
Code32Len equ $ - CODE32_SEG



不要值抄写代码运行,一旦代码不能带到目的就重抄一遍。这是不可取得。一定要自己慢慢调试,从内存角度理解每一条指令所起得作用,从内存去查看代码不能达到目的的原由。当然代码不可能一次成功,所以Bochs自带调试命令。
1、在某个物理地址设置断点
b addr b 0x7c00

2、显示当前所有断点的信息
info break

3、继续执行直到遇到断点
c

4、单步执行
s

5、单步执行,遇到函数则跳过
n

6、查看寄存器信息
info cpu
r
fp
sreg
creg

7、查看堆栈
print-stack

8、查看内存物理地址内容
xp /nuf addr xp /40bx 0x9013e
其中nuf表示大小,addr表示首地址

9、查看线性地址内容
x /nuf addr x /40bx 0x13e

10、反汇编一段内存
u start end u 0x30400 0x3040d

11、反汇编执行的每条指令
trace-on

12、每执行一条指令就打印cpu信息
trace-reg on
关闭trace-reg off
下面就是上述代码得结果。在屏幕中打印了一行红色的字

[img]http://dl.iteye.com/upload/attachment/0065/9731/10a55c72-10df-36c2-a350-154956ca99a4.png[/img]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值