如何调试从实模式切换到保护模式的程序

来源:互联网 发布:sql常用函数 编辑:程序博客网 时间:2024/05/14 00:15

如何调试从实模式切换到保护模式的程序

群号:2622452

作者QQ号:44008176

在学习操作系统原理及实现的过程中,经常需要编写从实模式切换到保护模式的程序,但这样的程序在虚拟机VPC中用debug根本无法调试,

下面的代码是从实模式到保护模式时的关键代码:

mov     eax,cr0

or      al,1

mov     cr0,eax

 

在用debug调试时,当步进到mov cr0,eax时,虚拟机就弹出如图所示对话框

 

 

不管你用DEBUG32还是其它的调试工具,一旦到了打开保护模式的大门时,必死无疑。这个问题困扰住了好多人,我遇到这个问题时,问了很多人,没人一个人能帮我解决,本人在这个问题上卡了好几个月,几乎放弃了对保护模式的学习。有一天,在网上无意中发现了一个网友的贴子,提供了一些思路,经过自己的实践,现整理如下:

 

解决办法:

1、众所周知,bochs具有调试操作系统的功能,所以考虑用bochs中的bochdbg进行调试, bochdbg启动会自动停在如图所示位置:

 

图中的地址f000:fff0bochdbg自动设置好的断点,这个断点是操作系统启动后都会经过的地方,所以操作系统启动后会停在断点f000:fff0处;

2、接下来我们可以用s 命令,让操作系统一步一步地去执行,直到操作系统启动完毕,但这只能观察操作系统的启动过程,并不能调试我们写的从实模式切换到保护模式的程序呀。

3、想法是这样的:当操作系统停在f000:fff0处时,我们可以设置一个断点,这个断点是我们写的程序一定会经过的地方,假设我们的程序在编写时有意的让他一定会经过某一个内存址,这样,我们可以在这里对这个有意安排的地址设置一个断点,等操作系统启动后,我们再执行自已写的程序,因程序一定会经过这个地址,所以就一定会在这个地址处停下来,这样,我们就可以用s命令一步一步地观察自己写的程序的运行情况了,

4、如何在自己编写的程序中有意的安排一个程序必定会经过的地址呢?

在程序运行时,在内存中的某个地址处以定义数据的形式(如:db 0cbh)放入一条retf语句,这样程序运行时就一定会经过个的绝对的地址,这个绝对的地址处设置断点,当操作系统启动后,接着运行程序,程序就一定会在这个断点处停下来,既然能停下来,我们就可以做任可观察这个程序运行的操作。

看如下代码:

           jmpseg   equ   40h      ; 定义一个常量jmpseg ,其值等于40h             

              mov      ax,jmpseg           ;

              mov    ds,ax                 ;令这个常量40h为数据段

              xor       si,si

              mov       ax,ds:[si]        ;

              push       ax       ; 把这个数据段起始处第一个字节保存下来(压入堆栈)

            mov      byte ptr ds:[si],0cbh  ;改写这个位置的值为 retf

              push      cs               ;向堆栈中压入retf返回后的段地址

              push      offset    back        ; 向堆栈中压入retf返回后的IP

              db      0eah              ;以定义数据的形式在内存中定义jmp 0x40:0指令,

              dw      0                  ;远跳转到0x40:0处,这个地址中就是retf

              dw      jmpseg

              back:                     ;执行retf后,返回,将弹出栈中的CSIP,刚好来到

              pop      ax                ; 标号back

              mov      ds:[si],ax             ;再恢复0x40:0处原来的值,  

堆栈情况如下:

retf返回准备的IP偏移地址

 

retf返回准备的段地址

保存的0x40:0处的原值

 

 

 

 

 

 


5、所以在虚拟地址0x40:0处设置断点,语法如下:

vb 0x40:0

这样,就在0x40:0处设置好了一个断点,

然后按c,让操作系统继续启动,操作系统启动后,接下来启动自己写的从实模式切换到保护模式的程序,程序一定会停在0x40:0处,接下来就可以使用bochs提供的各种命令观察这个程序是如何从实模式切换到保护模式了。

 

具体实现:

本例使用一张虚拟软盘镜像文件,该软盘镜像中可从作者的群共享中下载,名称叫:“bochs配置文件”压缩包,软盘中安装有msdos7.1,以及读者写的一个从实模式切换到保护模式的汇编程序rtop1.exe,(masm编译后生成)

1、将述代码复制到你写的从实模式切换到保护模式的程序开头处,举例如下:

 

RCodeSeg        SEGMENT PARA USE16

                ASSUME  CS:RCodeSeg,DS:RDataSeg

;----------------------------------------------------------------------------

Start           PROC

                            复制到这里

                            mov     ax,RDataSeg         ;从这往后是正式的代码

                mov     ds,ax

                cld

                            ……

Start                            ENDP

编译链接该程序,生成exe文件,本例中叫rtop1.exe

2、  安装虚拟机软件bochsVPC5.2,这两个软件读者可到我的群中下载,网上也有。

3、  生成一个软盘镜像文件(*.img),本例中这个镜像文件叫MSDOS.img当中安装msdos,一定要让虚拟机能从这张软盘中启动,vpc5.2中载入这个软盘镜像文件,把编译好的汇编程序rtop1.exe复制到这个软盘中.

4、  再将这个软盘文件复制到到bochs目录中,并配置bochs从这张软盘启动,相关配置语句如下:

# what disk images will be used

floppya: 1_44=msdos.img, status=inserted   从软盘msdos.img启动

 

5、  执行godbg.bat启动bochdbg,稍候片刻,操作系统停在f000:fff0,godbg.bat批处理文件在群共享中的“bochs配置文件”中,读者自行下载分析)

godbg.bat批处理文件的内容如下:

cd "C:/Program Files/Bochs-2.3.6/msdos"

../bochsdbg -q -f bochsrc.bxrc

6、  设置断点 vb x040:0

7、  c,让操作系统继续启动,

8、  操作系统后,停在命令行提示符处,

9、  bochs的另一个窗口中执行rmtopm.exe

10、              rmtopm.exe执行后一定会停在0x40:0,接下来就可以做任可观察这个程序运行的操作

具体bochs中的调试命令大家可以到网上查找

 

备注:读者在实际操作中可如下操作,安装好bochsVPC5.2后,将群中的MSDOS文件夹复制到bochs中,执行这个文件夹中的godbg.bat即可启动bochdbg,免去配置bochs的烦琐操作,在MSDOS文件夹中,bochs操作所需的配置文件都已设置好。

 

群号:2622452

QQ号:44008176