前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >试一试在没有操作系统的机器上运行下我们的代码

试一试在没有操作系统的机器上运行下我们的代码

作者头像
xujjj
发布2020-05-18 14:54:25
1.1K0
发布2020-05-18 14:54:25
举报
文章被收录于专栏:IT界的泥石流

Hello,小伙伴们大家好,在上一篇文章中(传送门:没有操作系统,也能运行我们的程序?(理论部分)),我们已经知道了一台计算机是如何加载操作系统到内存之中的。在这里简单的回顾一下,首先CPU先执行ROM中的BIOS程序进行硬件自检,硬件没问题之后,BIOS程序开始加载硬盘第一个扇区共512个字节到内存中,这512个字节是操作系统的引导代码,是专门引导操作系统的,因此这个扇区也叫主引导扇区。CPU执行操作系统引导代码,将操作系统的核心部分加载到内存中,这样操作系统就跑起来了,计算机就有灵魂了。好了,当然,我们也可以把我们的代码放到硬盘的第一个扇区,然后按下开机键,让BIOS把我们的代码加载到内存中,让CPU去执行我们的代码,这样,就实现了在计算机裸机上直接去运行我们的代码了。OK,我们开始动手做下实验吧。

首先先介绍一下我们的代码,我们的代码的功能是直接在显示屏显示“Hello,ITNiShiLiu”的字样,因此我们首先来介绍下如何在显示屏显示我们的字。为显示屏提供显示内容的是显卡,然后显卡的存储器就存放着要显示的内容,显卡的存储器称为显存。

在执行BIOS程序的时候,BIOS会执行一个硬件的初始化,它会将显存的显示模式初始化为80*25的文本模式。那么80*25的文本模式是怎么样的呢?我们来看一下下面这幅图。

80*25说明显示器可以显示80列*25行的字符个数,显存的两个字节对应显示屏上的一个字符,在每两个字节中,一个字节存放字符的ASCII编码,另一个字节存放字符的属性,比如颜色、背景色这些属性值,每两个字节经过字符发生器的解析之后,再在显示器中显示出来。

用一个字节表示属性,就是如下图这样,去表示每个字符的属性的。

好了,明白了显示字符到显示屏的原理之后,我们还要明白,显存到底在哪个位置?

在Intel 8086为基础的处理器中,规定了地址范围为B8000~BFFFF为显存的地址范围,因此我们需要从B8000开始存放我们所要显示的内容即可。

好了,下面我们开始写代码了。。。

我们使用NASM-IDE编写代码,编写完之后,使用NASM编译器对代码进行编译。根据以上思路,我们要把要显示的字符写入到地址B8000开始的位置处,所以我们的段地址为B800。段地址我们采用ES寄存器保存起来。

有了段地址之后,我们就可以通过递增偏移地址开始写数据了,一个字节一个字节地写数据进去显存。第一个字节写进es:0x00的位置处(也即B8000的地址),第二个字节写进es:0x01的位置处(即B8001的地址)。

接下里,我们依次类推,将"Hello,ITNiShiLiu"中的字符依次写进显存中。

代码语言:txt
复制
mov byte [es:0x02],'e'
mov byte[es:0x03],0x07

mov byte[es:0x04],'l'
mov byte[es:0x05],0x07

mov byte[es:0x06],'l'
mov byte[es:0x07],0x07

mov byte[es:0x08],'o'
mov byte[es:0x09],0x07

mov byte[es:0x0a],','
mov byte[es:0x0b],0x07

mov byte[es:0x0c],"I"
mov byte[es:0x0d],0x07

mov byte[es:0x0e],'T'
mov byte[es:0x0f],0x07

mov byte[es:0x10],'N'
mov byte[es:0x11],0x07

mov byte[es:0x12],'i'
mov byte[es:0x13],0x07

mov byte[es:0x14],'S'
mov byte[es:0x15],0x07

mov byte[es:0x16],'h'
mov byte[es:0x17],0x07

mov byte[es:0x18],'i'
mov byte[es:0x19],0x07

mov byte[es:0x1a],'L'
mov byte[es:0x1b],0x07

mov byte[es:0x1c],'i'
mov byte[es:0x1d],0x07

mov byte[es:0x1e],'u'
mov byte[es:0x1f],0x07

最后,由于主引导扇区的大小为512个字节,而且主引导扇区要以"55 AA"两个字节作为结束标志,或者称魔数。每次执行主引导扇区代码时都会首先检查该主引导扇区最后2字节是否是"55 AA",若是,则会执行主引导扇区,否则,则认为这是一个无效的主引导扇区,停止执行。因此,我们要将我们编译之后的代码凑够512个字节,并且在最后两个字节使用“55 AA”作为结束标志。

OK,代码已经写完了,使用NASM编译器编译一下,得到了bin文件,即为二进制文件。因此我们的代码就被编译为基于Intel 8086处理器的机器指令了。我们可以使用HexViewer工具查看编译后的机器指令,并且它的确是512个字节,最后两个字节为“55 AA”。

最后我们要把这个bin文件写进硬盘开始的512个字节位置处,也即硬盘的第一扇区。怎么完成这个过程呢,我们可以首先在网上下载一个虚拟磁盘VHD软件,它是一个虚拟磁盘,我们用它来模拟我们的硬盘。同时我们再下载一个Vhd Writer软件,该款软件可以对我们的VHD虚拟磁盘进行管理,可以进行写入操作。下载完毕之后,打开Vhd Writer对虚拟磁盘进行写入操作,对虚拟磁盘的第一个扇区写入我们的bin文件。

到此,就将我们的bin文件写入到虚拟磁盘中了。

接下来,我们使用Virtual Box创建一台没有操作系统的虚拟机,然后将我们的虚拟硬盘挂上去。

然后将我们的虚拟硬盘给挂进去,这样,这块硬盘就成为了这台计算机的硬盘了。

创建完成之后,由于该虚拟磁盘已经写入了我们的代码了,我们按下启动按钮,启动我们这台没有操作系统的计算机。

启动成功,我们可以看到,我们的代码在这台没有操作系统的计算机上跑起来了!并在屏幕上显示“Hello,ITNiShiLiu”

上述所使用的工具大家可以自行百度下载,差别不大,能用即可。

完整代码

代码语言:txt
复制
mov ax,0xb800
;将b800传送到ax寄存器中
mov es,ax
;将ax寄存器中的值,也就是b800传送到附加段寄存器es中
;为什么不写成  mov es,b800 ?
;因为intel处理器不允许,它只允许:mov 段寄存器,通用寄存器/内存单元
;b800这个数是干什么用的?---显存的段地址
;-----------------------------------------------------------------
mov byte[es:0x00],'H'
;将"字符L的ASCII码"存储到显存的第1个存储单元中
;mov byte[es:0x00],0100 1100b / 76 / 0x4C
;地址必须使用方括号括起来
;byte/word:明确的告诉编译器这条指令的数据宽度
;不需要修饰:Mov  [00],AL  /  Mov  AX,[00]
mov byte[es:0x01],0x07
;将"字符L的属性"存储到显存的第2个存储单元中
;属性值07:黑底白字、无闪烁、无加亮

mov byte[es:0x02],'e'
mov byte[es:0x03],0x07

mov byte[es:0x04],'l'
mov byte[es:0x05],0x07

mov byte[es:0x06],'l'
mov byte[es:0x07],0x07

mov byte[es:0x08],'o'
mov byte[es:0x09],0x07

mov byte[es:0x0a],','
mov byte[es:0x0b],0x07

mov byte[es:0x0c],"I"
mov byte[es:0x0d],0x07

mov byte[es:0x0e],'T'
mov byte[es:0x0f],0x07

mov byte[es:0x10],'N'
mov byte[es:0x11],0x07

mov byte[es:0x12],'i'
mov byte[es:0x13],0x07

mov byte[es:0x14],'S'
mov byte[es:0x15],0x07

mov byte[es:0x16],'h'
mov byte[es:0x17],0x07

mov byte[es:0x18],'i'
mov byte[es:0x19],0x07

mov byte[es:0x1a],'L'
mov byte[es:0x1b],0x07

mov byte[es:0x1c],'i'
mov byte[es:0x1d],0x07

mov byte[es:0x1e],'u'
mov byte[es:0x1f],0x07



times 313db 0
;让编译器重复生成db 0---- 313次,即313个字节
db 0x55,0xaa
;硬盘主引导扇区的有效标志

好了,本次的分享就到这里了,感谢大家的阅读与支持,如有错误,欢迎留言指出和交流!我们下期再见!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT界的泥石流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档