Bochs虚拟机 & 编写主引导扇区程序并执行

bochs虚拟机是一个带调试器的虚拟机

Bochs是一种十分轻便的使用c++编写的开源IA-32(x86)电脑模拟器

现实中专业的调试器又很多,但是它们只能调试那些符合操作系统要求的程序,而不能调试只包含处理器指令的程序

 

bin文件操作系统不能执行,但是处理器可以直接执行
bin文件包含的都是机器指令

 

 

 

创建一个固定尺寸的VHD虚拟硬盘并安装在Bochs虚拟机上

使用virtualbox创建VHD虚拟硬盘

 

得到创建VHD虚拟磁盘的柱面数、磁头数和每道扇区数

fixvhdwr.exe

可以看到有602个柱面,4个磁头,每道17个扇区

注意这个fixvhdwr.exe只能打开virtualbox创建的VHD虚拟磁盘文件,其他软件创建的都打不开

 

打开bochs,配置Learn.vhd硬盘

此时,虚拟硬盘里面还是什么内容也没有

 

创建主引导扇区

exam.asm

mov ax,0x30
mov dx,0xC0
add ax,dx

使用nasm编译成exam.bin

用十六进制打开

8个字节

如何保证主引导扇区是有效的呢

      如果主引导扇区是无效的,上面并非是一些我们有意写的东西,而处理器又不加鉴别地执行了它,其结果是导致处理器的执行出现异常。为此,计算机的设计者们决定,一个有效的主引导扇区,其最后两个字节的数据必须是十六进制的55,AA

 

并且,我们需要在exam.asm基础上,再添加一些东西来凑够512个字节

mov ax,0x30
mov dx,0xC0
add ax,dx

times 502 db 0 ;重复伪指令db 0 502次
db 0x55
db 0xAA

db是伪指令,向程序中添加一个字节的数据

伪指令就是不是真正的处理器指令
它是让编译器做事而不是让处理器做事

times是nasm编译器的指令
 

这样就生成了一个合法的主引导扇区程序

 

将程序写入硬盘主引导扇区

主引导扇区是0面0道1扇区

使用fixvhdwr.exe, 打开Learn.vhd

 

LBA逻辑块地址

传统上,为了读写硬盘,我们必须指定柱面号(磁道号)、磁头号和扇区号

采用磁道(Cylinder)、磁头(Header)和扇区(Sector)这样的模式来访问硬盘的方法叫做CHS模式

每次读写硬盘都要考虑这三个,很麻烦。如果我们将硬盘的所有扇区统一编号,读写时只需要这一个编号,这样就很方便

于是就引入了逻辑块地址(LBA, Logical Block Address)的概念

现在市场上销售的硬盘,无论是哪个厂家生产的,都支持LBA模式

LBA模式是由硬盘控制器在硬件一级上提供支持,效率很高,兼容性很好

 

用调试器观察程序的运行

bochs.exe启动后是作为一个普通的虚拟机来运行,没有调试功能

bochsdbg.exe启动后是作为一个带有调试器的虚拟机,可以利用它做调试工作

 

下面启动bochsdbg.exe

直接点击start

右边是虚拟机的显示器,左边是调试窗口

 

boches虚拟机在加电时候就会开始取指令和执行指令

但是与真正的虚拟机不同,bochs在取第一条指令之前会先停下来,等待你的第一条命令,光标上面显示的就是下一条即将执行的指令

[0x0000fffffff0]是这条指令所在的物理内存地址

f000:fff0 可以理解为这条指令的逻辑内存地址,但实际上是段寄存器cs和指令指针寄存器IP在此时此刻的内容

这和8086是不一样的,8086启动时,CS内容是ffff,IP是0

jmpf 0xf000:e05b是这条指令的汇编语言形式

最后的ea5be000f0是这条指令的机器码,处理器代码

 

sreg显示段寄存器

r显示通用寄存器

 

AX是16位的

EAX是32位的,AX依然可以使用

RAX是64位的,EAX依然可以使用

 

BX,CX,DX也都是这样

 

 

s 单步执行

b 设置断点(实现设置一个内存地址,当处理器执行到这个内存地址时就会自动停下来)

c 继续执行

q退出

 

计算机在启动后总是把主引导程序加载到物理内存地址7C00处

所以给0x7C00设置断点

再输入c,继续执行

此时程序出现了问题,显示没有可以启动的设备

点kill simulation就是取消本次调试

 

再次打开bochsdbg.exe

重新设置硬盘

将配置保存起来,不是只对本次启动有效

重新启动

设置断点,continue

可以看到已经执行了17404836条指令,真滴好多鸭

下一条要执行的指令就是mov ax, 0x0030

就是我们编写的第一句了

之后我们就可以用s和r,单步执行和查看寄存器了

但是一旦执行3条命令之后全是0的命令就不能执行了,否则会出错的

之后按q退出

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章