当前位置: 首页 > news >正文

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退出

 

 

 

相关文章:

  • 编译原理2.1
  • Python 函数式编程(一):高阶函数/函数名变量
  • Pycharm debug
  • MyOS(二):用Java和汇编开发一个helloworld操作系统内核
  • 仿QQ聊天室项目
  • 基于Python+Flask+Echarts的 COVID-19数据可视化项目
  • go语言相关知识
  • go语言相关库和函数
  • Windows内核文件
  • MyOS(三):软盘读写
  • Python函数式编程(二):map、 reduce、 filter、 sorted
  • OpenCV(一)——图片灰度转换(灰度图) 修改图片尺寸(cv2.resize) 读取视频
  • opencv人脸识别 (一):人脸检测 (Haar级联 静态图像中人脸检测 视频中的人脸检测 )
  • opencv人脸识别 (二):人脸识别 (基于 LBPH)
  • Caffe(一)——简介 优点 Caffe2 编译和安装
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • exif信息对照
  • Idea+maven+scala构建包并在spark on yarn 运行
  • JavaScript标准库系列——Math对象和Date对象(二)
  • jdbc就是这么简单
  • JDK 6和JDK 7中的substring()方法
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Octave 入门
  • React16时代,该用什么姿势写 React ?
  • Redash本地开发环境搭建
  • Redux 中间件分析
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • vagrant 添加本地 box 安装 laravel homestead
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • Vue小说阅读器(仿追书神器)
  • webpack+react项目初体验——记录我的webpack环境配置
  • 创建一种深思熟虑的文化
  • 代理模式
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 扑朔迷离的属性和特性【彻底弄清】
  • 入门到放弃node系列之Hello Word篇
  • 时间复杂度与空间复杂度分析
  • 使用 Docker 部署 Spring Boot项目
  • 为什么要用IPython/Jupyter?
  • 小李飞刀:SQL题目刷起来!
  • 阿里云API、SDK和CLI应用实践方案
  • ​用户画像从0到100的构建思路
  • (2.2w字)前端单元测试之Jest详解篇
  • (3)STL算法之搜索
  • (python)数据结构---字典
  • (笔试题)分解质因式
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)spring boot基于小程序酒店疫情系统 毕业设计 091931
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (算法)前K大的和
  • (一)插入排序
  • (转)jdk与jre的区别
  • (转)Linq学习笔记
  • (转)linux下的时间函数使用