动手制作操作系统——一点分析问题的经验
2016-05-19 12:42
316 查看
书中讲解ldt部分的例子和代码很简单,本以为抄完运行一下马上就能结束这章。但是很尴尬,在抄完书中的代码后,编译运行,实际运行的结果和书中的结果并不一样,程序只运行了一半就导致系统崩溃了,干瞪眼看代码看了半天,和书中的代码明明写的一样,那么为什么会出现这个问题呢?
书中程序运行在FreeDOS上,大致意思如下:
在程序开头部分建立GDT,LDT和GDT选择子,LDT选择子等,等程序加载至内存后,
1、跳至一个在实模式下运行的代码段,这段代码负责初始化GDT,LDT中的描述符和进入保护模式的准备工作(记做A代码段);
2、跳至保护模式,一个32位的代码段(记做B代码段),在这里显示一串字符串;
3、进入LDT中的一个描述符所表示的代码段(记做C代码段),这里显示一个字符L;
4、回到实模式,程序结束。
而我的程序写完后,只输出了字符串,C代码段中的'L'并未显示,系统就崩溃了
首先粗略分析问题,B中的字符串已经显示成功,C中的'L'未显示,那么问题大致的位置就定位在A或者A之前
第一个问题来了,由于这个示例程序是运行在FreeDos上的,我们的程序被Dos加载到内存中什么地方我是不知道的,而bochsdbg想要设置断点就必须要知道程序的运行地址,我应该怎么设置断点?。
在网上找到了一个方法:
1、在程序开头处建立一个标记LABEL_BEGIN;
2、向400h:0处(也可以别的未被占用的内存地址)写入代表跳转至LABEL BEGIN 处(jmp far)的16进制机器码;
3、跳至400h;0处
然后在操作系统运行前在400h:0处设置断点,就可以调试程序了。
解决无法调试的问题后单步执行程序,执行完跳转至C代码段的指令后。程序跳转到了一个奇怪的地址,不是C代码段所在的地址,显然,问题出在建立或者初始化GDT,LDT,选择子的部分上
那么单步执行程序至加载完LDT处,用info ldt命令查看GDT和LDT,GDT中的LDT描述符的段基址和段界限中没有问题,而LDT中唯一的描述符基址出现了错误,为0x00002600,与应该得到的结果0x00032600不符,至此,问题的位置已经找到了,就在A中 初始化LDT中的描述符(记做D)处。
继续调试D处的代码,明明应该右移的数据却左移了,我将我抄写完的代码中的D处和书中的代码的D处对比了一下,发现,原来只是因为我把书中的shr抄成了shl。只因为一个字符,指令的含义完全改变了。整个程序就因为这一个字符而崩溃。
问题虽小但是解决这个问题的过程也收获很多经验,遇到bug的大致思路就是:大致定位问题,找出问题发生的具体位置,解决问题。
书中程序运行在FreeDOS上,大致意思如下:
在程序开头部分建立GDT,LDT和GDT选择子,LDT选择子等,等程序加载至内存后,
1、跳至一个在实模式下运行的代码段,这段代码负责初始化GDT,LDT中的描述符和进入保护模式的准备工作(记做A代码段);
2、跳至保护模式,一个32位的代码段(记做B代码段),在这里显示一串字符串;
3、进入LDT中的一个描述符所表示的代码段(记做C代码段),这里显示一个字符L;
4、回到实模式,程序结束。
而我的程序写完后,只输出了字符串,C代码段中的'L'并未显示,系统就崩溃了
首先粗略分析问题,B中的字符串已经显示成功,C中的'L'未显示,那么问题大致的位置就定位在A或者A之前
第一个问题来了,由于这个示例程序是运行在FreeDos上的,我们的程序被Dos加载到内存中什么地方我是不知道的,而bochsdbg想要设置断点就必须要知道程序的运行地址,我应该怎么设置断点?。
在网上找到了一个方法:
1、在程序开头处建立一个标记LABEL_BEGIN;
2、向400h:0处(也可以别的未被占用的内存地址)写入代表跳转至LABEL BEGIN 处(jmp far)的16进制机器码;
3、跳至400h;0处
然后在操作系统运行前在400h:0处设置断点,就可以调试程序了。
解决无法调试的问题后单步执行程序,执行完跳转至C代码段的指令后。程序跳转到了一个奇怪的地址,不是C代码段所在的地址,显然,问题出在建立或者初始化GDT,LDT,选择子的部分上
那么单步执行程序至加载完LDT处,用info ldt命令查看GDT和LDT,GDT中的LDT描述符的段基址和段界限中没有问题,而LDT中唯一的描述符基址出现了错误,为0x00002600,与应该得到的结果0x00032600不符,至此,问题的位置已经找到了,就在A中 初始化LDT中的描述符(记做D)处。
继续调试D处的代码,明明应该右移的数据却左移了,我将我抄写完的代码中的D处和书中的代码的D处对比了一下,发现,原来只是因为我把书中的shr抄成了shl。只因为一个字符,指令的含义完全改变了。整个程序就因为这一个字符而崩溃。
问题虽小但是解决这个问题的过程也收获很多经验,遇到bug的大致思路就是:大致定位问题,找出问题发生的具体位置,解决问题。
相关文章推荐
- maven使用经验集
- 应用领航:盘点那些年我们一起追过的OS
- 无奇不有!盘点各国自己开发的操作系统
- 样式表CSS布局经验
- 路由器之基本维护经验
- 可自定义oem的萝卜家园 Ghost XP 新春装机版 V200801 下载
- C#实现判断操作系统是否为Win8以上版本
- 学习C和C++的9点经验总结
- 非常不错的MySQL优化的8条经验
- js获取本机操作系统类型的两种方法
- Linux操作系统添加新硬盘方法
- java如何获取本地操作系统进程列表
- Linux rdesktop操作系统下远程登录Windows XP桌面
- 32位操作系统认出超出4G内存的方法
- Linux rpm tar 操作系统下软件的安装与卸载方法
- JavaScript 获取用户客户端操作系统版本
- jsp 获取客户端的浏览器和操作系统信息
- Windows 操作系统的安全设置
- php判断当前操作系统类型
- PHP获取用户的浏览器与操作系统信息的代码