7.如何执行编译好的程序
课时30 8086加电或者复位时的状态
介绍如何跳过操作系统来执行我们编译后的程序。
这一课首先介绍8086处理器加电复位时的状态和动作
这一部分,我们来研究如何让处理器执行编译好的程序
这一课的任务时研究,当计算机启动时,8086处理器的状态
在前面,我们已经通过编译生成了包括处理器指令的文件,exam.bin
既然包含了处理器指令,那么就表明处理器可以直接执行
那赶紧去执行啊。但是这并不是一件容易的事情
但是前面还有一道屏障,那就时操作系统。
对于Linxu和windos,为我们使用计算机提供方便
但是我们如果想去和处理器直接对话的时候, 它又是我们和处理器中间的一道墙。
很难绕开他,。
对于绝大多数编译好的程序来说,
要想得到处理器的光顾,让它执行一下,必须借助操作系统。
拿windos来说。为你显示每个程序的图标。
允许你双击来运行
在内部看不见的层面上,它必须给每一个要运行的程序的分配空闲的内存空间
并在适当的时候提交给处理器去执行。
每一种操作系统,都对它管理的程序,提出了种种格式上的要求
比如,它要求编译好的程序,必须在文件的开始部分,包含编译日期,
是针对那种操作系统编译的,是什么版本,第一条指令从哪里开始
数据段从哪里开始?有多长?代码段从哪里开始,有多长?等等
windos建议你在文件中包含一个用于显示的图标,如果你不按要求来。
他也不会给你面子,并直接弹出一个对话框
告诉你他不准备,也没有办法,将你的程序提交给 CPU执行
举个例子
windos的执行程序,通常是以.exe为扩展名的
将exam.bin,修改为.exe,来伪装成一个可执行程序。
毕竟这也不能说是伪装。
毕竟这个文件里边就是包含了处理器指令。
原则上应该可以执行
如果改变文件扩展名,会不可用,确实要改么?
是!
就会编程windos可执行文件。
并不会执行
因为,这个文件的格式,并不符合windos的要求
所以他在加载的时候,会发现文件不合法
虽然他包含了处理器指令,但是并不符合windos的要求
选择1,按照windos要求生成一个合格的程序
NASM可以做到这一点,但是我们要付出代价,
因为windos,不允许我们直接访问硬件
也不允许,我们直接控制硬件
你想决定把程序放到哪里?你想直接访问硬盘?那是不可能的/
你可以提要求,就像你可以点菜,但是不能和厨师见面
选择2.学习汇编就是要进行直接控制硬件
那么什么事情都有操作系统来代理,那有什么意思?
不过没关系,我们还有另外的一种选择
在一个完整下系统中,
最底层是处理器
处理器的上面是操作系统
操作系统上面是各种各样的应用程序
应用程序都依赖于操作系统,
在特定的操作系统开发一款软件,肯定不是一件容易的事情。
但是换个角度来考虑一下,操作系统也是一个需要在处理器上运行的软件
比起一般的软件来说,不过是功能复杂,体积庞大而已
当我们开机的时候,处理器首先执行的就是操作系统
这样说来,如果我们能绕过操作系统,并能代替他,
让计算机一开机的时候,就直接执行我们自己的软件,岂不是更简单么。
那就慢慢开始
首先需要了解,在计算机加电启动时,处理器都做了写什么?
每当我们加电开机之后。
处理器都会执行一个硬件初始化,以及一个可选择的内部自测试。
然后将内部所有寄存器的内容都初始到一个预置的状态。
在我们的计算机上,会有一个热启动按钮,很多都知道
热启动按钮和处理器的reset引脚相连。
这就时reset引脚,在处理器上
当我们按下reset引脚的时候,就会向reset引脚发送一个信号。
这同样会导致处理器会执行硬件初始化和内部自测试,并将内部所有寄存器的内容,初始到一个预置的状态。
对于因特尔8086来说,复位操作,将使代码段寄存器CS的内容FFFF
而对于所有的其他寄存器来说,他们的内容都会被初始化为零,
包括所有的通用寄存器,以及所有的段寄存器。
和指令指针寄存器
都会被初始化为零
只有代码段寄存器的内容时4个FFFF
在这里有两点需要特别说明
第一,以上只是8086加电上的状态;
后续的处理器并没有延续这样的设计;
也就时说,我们刚才所描述的处理器的状态,在加电之后的状态,只适用于8086,
而不适合于别的新的处理器。
8086有三个段寄存器,
段寄存器ES,我们前面没有讲过。
这里已经画出来。
和DS一样,ES也是一个数据段寄存器
因为是一个附加的数据段寄存器,所以叫附加段寄存器ES
为什么需要它呢?
为了访问数据,需要用数据段寄存器。
但有的时候需要在两个段之间来回操作
一个数据段寄存器,可能不够用。
所以有添加了新的 附加段寄存器ES,
处理器的主要功能是取指令和执行指令,
在加电或者复位之后,就会立刻去尝试这样的工作。
立刻去取指令和执行指令,
取指令就要发出地址,那么
当处理器加电或者复位之后,发出的第一个地址是什么呢?
在处理器加电或者复位之后,段寄存器CS的内容,是四个F
FFFF
指令指针寄存器的内容是四个0
0000
8086是将段寄存器CS的内容左移四位,编程FFFF0‘
然后,同指令指针寄存器IP的值0,相加
然后结果是20位的FFFF 0
、
然后把这个地址送到地址线上去,
然后取内存去取第一条指令,取内存。
那么地址FFFF 0 是在哪里呢?
请看
这个地址位于内存空间的高端
它距离最顶端,距离内存的最顶端 只有十六个字节
8086就是从这里开始取指令,并开始执行指令的。
问题是,刚刚加电或者复位的时候,整个内存里边。
有指令可以执行吗?
这是个问题,很重要的问题?
课时31 8086地址空间的分配
介绍8086可访问的地址空间由哪几部分组成,以及各部分的介绍。
但是这并不意味着被访问的内存, 在物理上是一个整体,事实上着个地址范围会被,地址分配电路,也就是着个电路。
分成几个独立的部分。
传统上,如果8086处理器发出的地址,介于00000 -9FFFF
就可以读,又可以写
这种内存,就是你眼前的物件。
我们平时称之为内存条。
内存是由字节组成,字节又是由比特组成
为了节约成本和集成度
每个比特的存储,是靠一个微小的晶体管
以及同样是及其微小的电容,
来完成的,
在学生时代,我们知道,电容可以充放电,。
因此,可以通过充电和放电来表示比特0 1
那时我们也知道,电容也容易泄露电荷
当一个电容如果充电之后,不管它,放到一边,它就会慢慢放电
直至存储的电荷慢慢消失,。
可以想象,组成这种内存的微小电容,泄露电荷的速度,当然也时非常快的
通常也在几个微秒之内,漏的一干二净
所以,这种内存,需要定期补充电荷,以维持原先存储的内容。
着个过程叫做动态刷新
因此这种存储器,也叫动态访问随机存储器,
简称。DRAM
刚才我们讲到了随机访问
随机访问的意思时,访问任何一个内存单元的速度,所话的时间和它的位置和地址无关
比如,从头到尾的录音带上找某首歌曲
歌曲的位置在录音带上,歌曲越靠前所花的时间,就越短。
歌曲在磁带上越靠后,找到它画的时间就越长,
但内存就不同
读写任何内存单元,所需要的时间时不一样的。
不管它的地址是靠前还是靠后,
在内存刷新期间,处理器当然是无法访问内存的。不过对于内存访问
刷新操作,所占用的时间还是微乎其微的。
他们可以错开进行。
显卡通过电缆连接显示器
给显示器发送视频信号,另外,它还要插在计算机的主板上
着就是一个计算机主板
通过打开计算机的机壳才能看见
在主板上,着个位置用来安装处理器
着四个插槽,用来插内存条
着个插槽和着2个白色插槽,用来插接口卡
注意观察,显卡的下边有一个卡后,俗称金手指,这些卡口,用来插入这些插槽
一旦插入之后,显示器,就通过接口卡,和计算机连接起来了。
显卡上有存储器
处理器,可以把要显示的文本内容
写入显卡上的存储器
然后显卡负责将他转换成视频信号,发送给显示器,
这样一来,我们就能够
在显示器上看见文本了。
但是很显然
8086必须能够访问的显卡上的存储器
不然怎么能够显示要显示的文本呢?
最后
如果8086处理器是介于F0000-FFFFF
那么8086将会访问一个特殊的存储芯片
叫做rom bios着个特殊的存储芯片
这种存储芯片,只能用来读取而不能写入
所以又叫做只读存储器,简称ROM
ROM是特殊手段来特殊写入的
在你眼前
这副图种是几种,不同的芯片。
这是一种四方的ROM芯片
着也是一种ROM芯片
中间的芯片本身
中间的在这个方框是插座
于前面两个芯片不一样
长方形的,它的引脚位于两侧
和DRAM内存条不同
只读存储器ROM
不需要刷新,它的内容是预先写入的,即使掉电也不消失。
但是也很难改变,有些rom的内容永远无法擦除和重写。
但是有些ROM则可以用紫外线或者加电来重写。
ROM的内容可以预先写入,即使是关掉电源也不会消失
着个特点非常重要。非常有用。
比如我们可以将一些指令固化在rom中
从8086处理器的视角来看
ROM占据着整个内存空间的顶端
着一部分是ROM
地址范围是F0000到FFFFF
ROM所占用的这一部分的空间,一共是64K字节
看DRAM
它占据着较低端的640K字节
从00000 - 9fffff大小是640K字节
中间分给了一些外围设备
显卡键盘控制器
A0000 EFFFF
这一部分A0000 - EFFFF 320KB
我们说过8086加电或者是复位的时候,发出的第一个地址是FFFF0
所以它取的第一个指令位于物理地址FFFF 0 正好位于ROM中,
所以着个地址方位的是着个ROM芯片,着个ROM芯片正好固化了开机的时候所需要的指令
着快ROM中是可执行的程序,用来对组成计算机的最基本的模块进行诊断,和初始化,在开机的时候,。
除此之外,有些硬件对于正常使用计算机来说,是必不可少的,
比如键盘,硬盘和显示器。
要使用这写硬件,需要编写复杂的程序
写了方便程序员使用这些硬件
这些ROM里,还固化了一些线程的程序,供我们调用
我们可以通过线程的程序来读取输入向设备输出,至于如何调用这些程序,后边讲解
无论如何,因为这些程序,是针对最基本的硬件来编写的,所以着快芯片,又叫做
基本输入输出系统,简称BIOS
问题在于地址为FFFF F 的着个单元
它距离内存的顶端,FFFF0,它们之间只有十六个单元
处理器处理的方向是从内存的低端向高端推进
这是处理器取指令和执行指令的方向
当处理器从FFFF0开始取指令和执行指令的时候,很快就执行到了内存的顶端。
着十六个字节起始放不了几个指令
所以也做不了什么事情
那么着以小块内存,放的是什么指令呢?
这些指令执行完了之后,怎么办嗯?
请听下回分解
课时32 跳转指令
介绍8086处理器的跳转指令及其作用
学习,如何让处理器从当前位置,跳到另一个内存地址处取指令并执行。
在上一集里,为了保证处理器在加电或者复位之后,能够有指令执行,内存的顶端,是ROM和BIOS
这里固化了开机程序
问题是处理器第一次取指令的意思是
FFFF0
这个位置距离内存的顶端
只有16个字节
存放不了几个指令
在着个位置,到底存放的是什么指令呢?
这里存放了一条特殊的指令,叫做跳转指令。
这条指令,是由五个字节组成。
这就是这条指令,5个字节
在我的机器上,是由五个字节。
其中,第一个字节EA是操作码
表示这是一个跳转指令
一般来说指令都是一条爱着一条集中存放的
处理器也是按照顺序一条一条的取出,并加以执行
可是,如果需要,处理器也可以离开当前位置,跳到内存当中的另一个位置
比如从这里跳到这里
开始从新取指令和执行指令。
除了往前跳也可以往后跳。
除非了发生了跳转了。否则处理器取指令和执行指令都是从内存的地址端向高地址端推进。
这个方向是永远不会变的。
处理器的跳转动作是由什么触发的呢?
是由跳转指令触发的
是由处理器的跳转指令触发的
所以触发了从一个位置跳到另一个位置
来去执行这个动作
在这一条指令中,第一个字节EA是这条指令的操作码
包含了几个方面的信息,这是一条跳转指令
第二,跳转的目标位置,仅仅跟在操作码的位置。
分别是十六位的偏移地址,和十六位的段地址
也就是说,在操作码的后边,前两个字节,5B和E0共同组成了偏移地址
后两个字节00F0共同组成了十六位的段地址
因特尔8086处理器是低端处理器是低端字节序的
逻辑地址F000:E05B
这条指令用汇编语言书写
JMP 0xF000:0xE05B(跳转到逻辑地址F000:E05B处取指令并执行)
在开机之后,在处理器内部,所有寄存器的内容,全都是零。
只有代码段CS的内容是FFFF
此时,处理器将段寄存器CS的内容,左移四位形成FFFF0然后在加上指令指针寄存器IP的内容0000
那么相加之后,形成20位的物理地址 FFFF0
把他放到地址线上,去内存中取指令
它取到的是这么一个跳转指令
当处理器加电或者复位之后,将取得这一个跳转指令,并加以执行。
在执行这条指令时,处理器用指令中的 段地址和偏移地址来修改CS,和IP的内容
那么当这条指令执行之后,段寄存器CS的内容被修改位F000
指令指针寄存器被修改位E05B
这是指令中的偏移地址
这条指令执行之后,
段寄存器CS的内容和指令指针寄存器IP的内容都被改变
着也是着一条指令执行之后的功能
改变寄存器CS和ip的内容
紧接着
处理器继续取指令和执行指令
和往常一样,是将段寄存器CS的内容
左移4位,形成F和4个零
然后和指令指针寄存器IP的内容
E05B相加
这样就形成了20位的物理地址
FE05B
并送到地址线去取指令。
此时,访问的是内存中的着个位置
然后从着个位置,向上顺序执行
着一部分依然是ROM BIOS的范围
里面固化了开机诊断,检测和初始化的程序
ROM BIOS的容量不大
存储不了多少东西
计算机要想做更多的事情,必须让处理器离开这个一成不变的环境
毕竟ROM BIOS 非常小
因此,在ROM BIOS也固化了一些指令
用来从外部的辅助存储设备,读取指令到内存里。
然后让处理器加以执行,
通俗的说,就是从U盘或者硬盘里面,读取程序,然后把他们放进内存
然后继续执行
通常来说,在硬盘和U盘里面,存在操作系统的代码
所以是从这些存储设备里面读取操作系统,然后执行操作系统代码从而启动操作系统
于是你就看到了LINUX和windos
在继续向下讲之前,了解一下硬盘的构造
课时33 硬盘的构造和工作原理
对硬盘的构造的原理进行介绍
处理器从内存中取指令和操作数,
外部存储设备是内存的后备存储设备,
而这些外部存储设备的内容,只有在加载到内存之后,
才能被处理器访问
所以,外部存储设备是相对于内部存储设备,内存来说的
外部存储设备的典型例子
是U盘和硬盘
着就是一个U盘
HHD 传统的寄电式硬盘
SSD 是最近若干年兴起的集成电路硬盘
寄电式硬盘是电子技术和机械的混合体,由机械的部分和电子电路组成,读写速度一般,很便宜。
这种集成电路硬盘,纯粹是由存储电路芯片组成,它的读写速度很快,但是,价格比较贵。
就算是在今天,这种寄电式在价格上占据统治地位
主要介绍寄电式硬盘
中间的盘片,圆盘,式用于记录数据的铝合金盘片,着个盘片固定在中心的轴上,这是一个轴
这个轴,由一个高速旋转的马达驱动,附着在盘片的扁平的锥状物,这个东西是用来读写数据的磁头。
它可以来回转动,硬盘是多盘片,密封,高转速的。
硬盘的盘片,采用的是铝合金作为片,并在表面涂上磁性物质来记录二进制比特
这样一来就使得它的盘片,具有较高的硬度,所以称之为硬盘。
主要就盘片的硬度而言的
铝合金的片,硬度较高,所以叫硬盘
给处更详细的图示。
硬盘可以只有一个盘片
也可以由很多个盘片,这里一共由6个盘片
无论如何,所有的盘片,都串在同一个轴上,
所有的盘片,都由电动机带着一起高速旋转,一般来说,转速达到每分钟3600转,而由的1W转
简写写RPM转每分钟
每个个盘面,都有两个磁头,磁头叫head比如
磁头是附着在盘片表面的,上下各一个,上面一个,下面一个。
通常,我们用磁头来指代盘面,因为每个盘面,都有一个磁头,。
所以我们都用一个磁头来指代一个盘面。
磁头都由编号。
从第一个盘面的第一个磁头开始编号。
编号为零
对于第一个盘片来说,上面的磁头编号为零,下面的磁头编号为1。
相应的对于第二个盘片来说,上面的磁头编号为2
下面的磁头,编号为3
每个磁头并不是单独移动,他们都是通过磁头臂固定在支架上。
前面是黑色的方块是磁头
这是一个磁头臂的支架
用来固定磁头臂
所有的磁头,都通过磁头臂都固定在一个支架上
然后是由步进电机带着一起在盘片的中心和边缘之间来回的移动。
也就是说,同进退的
由步进电机来驱动磁头。
而步进电机,是由脉冲驱动。
每一次,可以旋转一个固定的角度。
就是可以步进一次
磁头臂,这是磁头。
然后这个磁头,由磁头带动,在盘片的中心,和边缘之间来回移动
来回摆动,这样来读写数据,
可以想象,当盘片高速旋转的时候,磁头,每步进一次,都会在从他所在的位置开始,绕着圆心画着一个看不见的圆圈
这就是磁道
起始磁道是看不见的
当磁头围绕着盘片的中心
在中心和边缘之间来回摆动的时候,都会画出一个又一个圆圈
看不到的圆环,着就是磁道。
磁道用英语说,是track
磁道是数据记录的轨迹。因为磁头都是联动的
所以每个盘面上同一个磁道
又可以形成一个虚拟圆柱,叫柱面,用英语来说,cylinder
着个盘片上的着个磁道,以及另一个盘片上的同一个磁道,形成一个虚拟的圆柱,称为柱面
磁道和盘片也要编号
编号是从盘面的的最边缘开始,向着圆心的方向,从零开始编号
比如说,在最边缘的磁道编号是0,然后依次是1,然后依次是2,然后依次往中间编号。
对于其他盘面来说,也是一样的。
也是依次编号
着个柱面是一个用来优化数据读写的概念
初看起来,用硬盘来记录数据的时候,
应该是先将一个盘面,填满之后,在填写另外一个盘面,
实际上移动磁头是一个机械的动作
看似很快,但是对于处理器来说却非常漫长
这就是寻道时间,为了加速数据在硬盘上的读写,最好的办法就是尽量保证磁头不动,。
这样当0面的磁道,不足以容纳要写入的数据的时候,当这一条磁道被写满了,然后数据还没有写完,
那么着个时候,就应当把剩余的数据写到另外的一条磁道上
就是盘片的下面的一条磁道,
因为我们处于正面,所以看不到背面
如果还写不下,那么就继续把剩余的部分写在,二面的同一条磁道上,比如说。
这一条 磁道,写满了。反面的同一条磁道也写满了。
那 是数据还有还没写下,那么就 继续写在第二个盘片上着一面 同一条磁道上。
换句话说,在硬盘上,数据的访问,是以柱面来组织的
移动磁头,消耗的时间比较长,所以尽量保证磁头不动,把数据都记录在同一个柱面的相同磁道上,
而不是说把数据按照同一盘面的不同磁道来记录。
不是这样,如果这样,效率非常低
实际上磁道还不是硬盘读写的最小单位
磁道还要进一步划分为扇区
比如说,虚线是磁道,那么虚线中的每一段都是一个扇区
可以看出,在将磁道划分出很多分段之后,每一部分都成扇形,着就是扇区的由来。
、每条磁道都可以划分出几个扇区
着就取决于磁盘的制造者
通常是63个扇区
而每个扇区都有以个编号,与磁头和磁道不同
扇区的编号都是从1开始的。
磁头的编号和磁道的编号,都是从零开始的
扇区是从1开始编号的
在每条磁道上,它的第一个扇区编号是1
最后一个扇区,它的编号,是63 。
这一点需要注意
扇区与扇区之间是一个间隙
是一个空白来间隔的
比如说,这是一个扇区,这是另外的一个扇区
他们之间有空白
叫做间隙,或者空白
再来看每个扇区
比如这个扇区
每个扇区是以扇区头开始,然后是512个字节的数据区
这是每一个扇区的组成
扇区头包含了每一个扇区自己的信息,。
主要有本扇区所在的磁道号,磁头号。以及本扇区自己的扇区号。
这些信息,用来供硬盘的订购机构来使用
现在硬盘还会在扇区的头部,包括一个指示扇区,是否健康的标志。
因为每个扇区来反复的读写之后,可能回损坏,这个时候这个标志
扇区头里面的这个标志
可以指示着个扇区是否健康,是否还能继续使用
(18条消息) 4.2.1 OS之磁盘的结构(磁盘、磁道、扇区、盘面、柱面、磁头)_BitHachi的博客-CSDN博客
https://blog.csdn.net/weixin_43914604/article/details/106387866
课时34 一切从主引导扇区开始
告诉你如何从主引导扇区开始我们后续的学习。
了解 如何通过主引导扇区正式开始我们的学习历程
前面说到当ROM,bios完成自己的使命之前
最后要最做的一件事,是从外部存储设备读取更多的指令来交给处理器执行。
现实的情况是,绝大多数时候,对于ROM bios来说,硬盘都是手写的外部存储设备
请看
内存中是ROM bios
在ROM BIOS里面
黄色的部分是处理器在离开rom之前所要执行的最后一段代码
这部分代码的最用是将硬盘的主引导扇区 读到内存地址07C00处,
然后用一个跳转指令跳到哪里继续执行
就是说,这部分代码是处理器在离开ROM BIOS之前
所执行的最后一段代码
这一段代码要从硬盘里面的主引导扇区,把它读到内存地址为07C00处
然后在用一个跳转指令跳到这里来继续执行
那么什么是主引导扇区呢?
在盘面上,最上面的盘面是0面,或者叫做0头
因为编号位于0的磁头是负责着个盘面的。
因为编号为0的磁头,负责着个盘面。
那么在这个盘面最外侧的磁道是0磁道。编号为0的磁道
在这一条磁道上,第一个扇区,编号为1 的扇区是主引导扇区
换句话说,在硬盘上 0面0道1扇区或者说0头0柱1扇区叫做主引导扇区
是主引导扇区
如果计算机的设置是从硬盘启动
那么ROM BIOS,将读取硬盘主引导扇区的内容
将它加载到内存地址07c00处
将硬盘的主引导扇区,加载到这个位置
然后用一个跳转指令,跳到这里继续执行
着个跳转指令是处理器的执行离开ROM bios时,所执行的最后一条指令
它的汇编语言的指令形式是JUMB 0X000:0X7C00
这是这一条指令的汇编语言形式
通常主引导扇区的功能,是继续从硬盘的其他部分读取更多的内容加以执行
像WINDOS的操作系统就是采用这种接力的方法, 把自己一步一步运行起来的。
就是说,在主引导扇区里,有一些代码,从硬盘的 其他部分来读取内容
这样来接力执行
这样的话,主引导扇区负责从硬盘的其他部分来读取操作系统的代码,把它读到内存呢,然后一步一步的接力执行
执行的最终结果,就是操作系统,然后启动
说到这里可以想象,如果把自己编译号的程序,写到主引导扇区,不也是可以让处理器执行么。
这是个好主意, 几乎值在不依赖于操作系统的情况之下,让我们的程序可以执行的唯一方法。
不过,坏消息的是,如果你改写了硬盘的主引导扇区,
那么你安装的windosORlinux。你正常使用的操作系统就会瘫痪,无法启动了。
那么我们该怎么办呢?
用你现有的计算上虚拟计算机,互不干扰
虚拟机: