x86汇编从实模式到保护模式-带你轻松入门编程-让CPU执行我们写的汇编指令02

上一篇x86汇编从实模式到保护模式-带你轻松入门编程-彻底理解程序的本质01

在上一篇,我们写了下面2条汇编指令

mov ax ,1

add ax , 2

由于汇编指令,CPU无法执行,所以我们用汇编编译器将汇编指令转化成了CPU指令.

打开test.bin

CPU指令在test.bin文件里。我们可以打开test.bin,看下里面的内容。

如果你用普通的软件打开test.bin,你会看到如下的内容

显示的是一串乱码,想要正确的打开这个文件,需要通过特殊的软件查看器。我这里提供了一个

没有的朋友,可以去如下下载

链接:https://pan.baidu.com/s/1zB9r5WwuTMIPNMlYl5HlvA 
提取码:5ndl

用HexView.exe打开test.bin

现在我就用HexView.exe打开test.bin,内容如下

可以发现

mov ax , 1 转化成了B8 01 00

add ax , 2 转化成了83 C0 02

如何让CPU执行我们刚刚编译的汇编指令

现在我们遇到了一个很麻烦的问题,就是如何让CPU去执行test.bin中的cpu指令。现在test.bin是保存在硬盘里的,而我们无法让CPU直接跳转到硬盘里去执行test.bin,为什么无法跳转?因为CPU的设计者,没有设计这个跳转电路。所幸的是CPU会从内存里获取cpu指令,然后在cpu内部自动开始执行。

因此解决问题的办法就是想办法将硬盘里的test.bin加载到内存里,然后告诉cpu test.bin在内存中的位置。

如何将硬盘里的test.bin加载到内存里

现在又有新问题了,我们应该如何将test.bin加载到内存里呢?先来看下如下的图

大家初次看到上面的流程图,有没有被吓到,别担心,我们来逐步分析。

先来看第一个步骤,我们打开电脑的电源,此时CPU开始工作了,CPU首先会去BIOS中读取CPU指令。这里BIOS实际上是主板上的一块芯片名称,它有自己的存储器,这个存储器在生产的时候,就预先往里面保存了很多的CPU指令。

这些CPU指令有2大作用。

第一:检测硬件是否有损坏,比如说,这些指令会检测内存条有没有坏掉,如果坏掉了,CPU就会停止工作。

第二:如果硬件检测通过,那么它就会将硬盘的第0扇区的内容复制到内存的0x7c00处。

0扇区的内容保存到内存的0x7c00后,BIOS程序,就会通知CPU到0x7c00这个位置去获取cpu指令,cpu获取到指令后,就会自动开始执行。

由以上的步骤,我们可以知道,只要我们将test.bin放到硬盘的第0扇区,然后启动电脑,BIOS会将test.bin放到内存的0x7c00,然后CPU就会去0x7c00获取指令,然后在cpu内部开始执行。

虽然我们已经知道要将test.bin放到硬盘的第0扇区,但现实却不允许我们这样做。因为现在你的windows操作系统的引导程序就是放在硬盘的第0扇区,如果你此时将test.bin放到0扇区,那就会覆盖掉操作系统的引导程序,到时你就再也无法启动windows了。

使用虚拟机来完成测试

那么此时又要咋搞呢?有一种解决办法就是,我们使用虚拟机。

虚拟机是一种很强大的软件,它可以用软件模拟一个CPU,内存,硬盘等硬件。可以这样说,真实计算机有的,虚拟机都可以模拟出来。大家可以看如下文章,将虚拟机和虚拟硬盘配置起来。

汇编语言学习01-virtualbox安装虚拟机

将test.bin的内容复制到虚拟硬盘的0扇区

打开,没有这个软件的朋友,到如下下载

链接:https://pan.baidu.com/s/1zB9r5WwuTMIPNMlYl5HlvA 
提取码:5ndl

点击选择虚拟硬盘文件

点击打开

点击下一步

点击选择,这里实际上就是选择test.bin

输入0,就代表0扇区

点击写入文件

启动虚拟机

OK,到此为止。花费了很多的功夫,现在虚拟机有了,虚拟硬盘的0扇区也写入了我们的cpu指令。按照我们之前的想法,现在只需要启动虚拟机,虚拟机中的cpu,就会到虚拟机的内存的0x7c00处加载指令,然后在虚拟机的CPU内部开始执行。

那么现在就启动虚拟机吧

点击启动

运行结果如下


当我们满心欢喜的启动虚拟机后,竟然弹出这么个玩意,很明显CPU并没有找到我们硬盘0扇区的test.bin,你是不是很困惑,刚刚我们明明已经将test.bin中的内容写入到0扇区了,为什么会找不到呢?
原因是这样,BIOS在读取0扇区的内容后,会检测0扇区的最后2个字节是不是以0x55和0xAA结尾,如果没有,BIOS就会认为0扇区的内容是无效的,于是它就拒绝让CPU去执行这部分代码。而我们的代码里,很明显没有以0x55 和0xAA结尾。所以导致test.bin被拒绝执行了。

在主扇区的末尾添加0x55和0xAA

既然知道了原因,那我们添加0x55和0xAA就是了。在test.asm中,改造如下

mov ax,1
add ax,2

hlt    
      
times 510-($-$$) db 0
                 db 0x55,0xaa

hlt执行后,CPU就会暂停工作,我希望CPU执行完mov ax,1和add ax,2之后,就先暂停

硬盘的每一个扇区是512字节,为了让0x55和0xaa恰好位于最后2字节。我用times 重复存储了510-($-$$)个0,注意这里的0没有任何意义,纯粹用于占位。

$代表当前行的偏移

$$代表开始处的偏移。

$-$$就表示当前使用了多少个字节的空间 

510 减去已经使用的字节空间就等于,还需要填充多少数据,才能到510字节。在510字节之后,再保存0x55和0xaa,就刚好是512字节了。

此时我们重新编译汇编指令,然后编译后的test.bin继续写入到虚拟硬盘的0扇区,此时再次启动虚拟机,效果如下

如果你发现窗口里,只有1个光标在闪烁的时候,就说明我们的指令被执行了。由于执行的结果,并没有输出到屏幕上。我们看不到任何的现象。实际计算的结果是保存在寄存器的ax里,并且结果是3.

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值