ASM:《X86汇编语言-从实模式到保护模式》1-4章:处理器,内存和硬盘基础

  其实很久之前就学完了实模式了,但是一直没有总结,感觉现在直接在书上做笔记的弊端就是有些知识点不能很很深刻地记下来(毕竟手写最明显的优点就是能深刻地记住知识,但是就是用太多的时间罢了)。一下内容都是一些这本书里面的知识和笔记。

★PART1:进制计数:

  1.  二进制到十进制的相互转换(带权乘法)

  a. 二进制转十进制,只要把每一个位都乘以2的相应阶数就可以了,(无论是整数部分还是小数部分)

  b. 比如:10110001B=1*27+0*26+1*25+1*24+0*23+0*22+0*21+1*20=293D,其他进制(八进制,十六进制)转十进制也是一样的,比如八进制转成十进制,只用把上式2的多少次方改成8的多少次方,前面系数还是按照八进制数来定。

  2.  十进制转二进制

      整数部分,就是直接的短除法

      

  比如将十进制数26转成二进制数就是上面这个样子,如果是转成八进制或者十六进制也是同理,只是相应的要把除数改为8或者16,从最后一个余数往前写即是答案。

  小数部分,如图(一直对小数部分乘以2直到小数部分为0)

  十进制整数转换成小数,有时候不一定能完全能把小数部分全部转化为0,不是所有的十进制的小数都能完全可以转化为二进制,比如4.7就是不能,所以为什么浮点数最后可能会出现float x=4.7,而储存的是4.7000...001这样的事情

  3.  十六进制数和二进制数相互转换(比较重要)

  学编程,其实就是和二进制数在打交道,但是二进制数写起来太长了,为了方便人们发明了十六进制数,如果你在VS调试的时候转去内存的时候,会看到一大堆十六进制数,一开始我不会十六 进制转成十进制看被别人笑了很久,其实这个也很简单,直接一张表记住就好了,有些复杂的转换直接用windows自带的计算器。

    

  同理八进制和二进制也有差不多的关系,其实就是十六进制的0-7的那一个子集,但是用的不是很多。

★PART2:X86-8086处理器,内存和指令

  1.  处理器和寄存器

  a. 处理器是一台电子计算机的核心,它会在振荡器脉冲的激励下,从内存中获得指令,并发起一系列由该指令所定义的操作。当这些操作结束后,它接着再取下一个指令。通常情况下,这个过   程是连续不断,循环往复的。

  b. 处理器实际上是一个集成电路,在处理器的底部或者四周,有大量的引脚,可以接受从外面来的电信号,或者向外发出电信号。处理器内部有一个基本部件:寄存器(Register),当引脚会向   处理器传送一系列电信号(如果处理器需要处理这些电信号),那么这些高低电平的组合(实际上代表二进制数),会被寄存器锁住,然后引脚和线路会马上被用于其他操作(如果存在)。这些内部线路被称为处理器的内部总线。

  c. 寄存器内的数据只能临时储存,而且寄存器是有大小的,有4位,8位,16位,32位,64位寄存器等等,这些分别代表着他可以储存4比特,8比特,16比特,32比特,64比特大小的数据。

  2.  内储存器(内存)

  内存按字节来组织,单次访问的最小单位是1字节,这是最基本的储存单元。内存的每个字节都对应着一个地址。第一个字节的地址是0001H,第二个字节的地址是0002H,以此类推。为了访问 内存,处理器需要给出一个地址,访问包括读和写,为此,处理器还要指明,本次访问是读访问还是写访问,如果是写访问,则还要给出待写入的数据(这个在以后访问硬件经常看到这种用法)。处理器可以只通过一次访问来处理8位,16位,32位或者64位数,而不是依次取出一个一个字节来组合

    3.  指令和指令集

  a. 关于高端字节序和低端字节序,其实这个我之前有收录过一篇文章,请戳,里面讲的比较详细。

  b. 数据和指令都是一堆二进制数,指令和数据要分开储存(当然你可以用指令去跳过数据区,这是后话了)。存放指令的区域叫代码区,存放数据的区域叫数据区,每个处理器都能识别有限个   指令,一个处理器能够识别的指令的集合,称为该处理器的指令集

  4.  Intel 8086处理器的通用寄存器

  a. 8086处理器内部有8个16位的通用寄存器,分别被命名为AX,BX,CX,DX,SI,DI,BP,SP,这些处理器的首字母和他的功能密切相关,比如AX是累加器(Accumulator)(与他有     关的指令还会做指令长度上的优化(把它们弄短));CX是计数器(Counter);DX是数据(Data)寄存器,除了作为通用寄存器使用外,还专门用于和外设只见进行数据传送(比如in和out指  令);SI是源索引寄存器(Source Index);DI是目标索引寄存器(Destination Index),用于数据传送操作(以后会在movsb和movsw指令中看到)。

  b. 处理器的内部寻址是不会用绝对内存地址(物理地址的),因为这样系统上运行的程序将无法重定位,为此,处理器在访问内存的时候使用了分段机制,实际上处理器会把内存分段,在分段   之后,各个地址只能相对于它自己所处的段中,然后加上偏移地址,就可以找到实际的物理地址了。为了实现这个分段的功能,处理器至少需要提供两个段寄存器,他们是代码段寄存器(CodeSegment,CS)和数据段寄存器(Data Segment,DS)。对CS的内容的改变将导致处理器从新的代码段开始执行,同样,在开始访问内存中的数据之前,也必须首先设置好DS寄存器,使之指向数据段。

  c. 8086是一个16位的处理器,它有AX,BX,CX,DX,SI,DI,BP,SP这八个通用寄存器,同时,前四个寄存器的每一个,都可以当成两个八位寄存器来使用,分别是AH,AL,BH,BL,CH,CL,DH,DL。在进行数据传送或者算术逻辑运算时,使用算术逻辑部件(ALU)。比如,将AX的内容和CS的内容相加,结果仍在AX中,那么,在想加的结果返回AX之前,需要通过一个叫数据暂存器的寄存器中转。为了加快指令执行速度,8086内部有一个6个字节的指令预存队列,在处理器忙着执行那些不需要访问内存的指令时,指令预存部件可以趁机访问内存预取指令。这6个指令流可以排队等候解码和执行。

  d. 8086内部有是个段寄存器,其中,CS是代码段寄存器,DS是数据段寄存器,ES是附加段(Extra Segment)寄存器(一般用来指向显卡的0xb8000段),如果程序需要访问数据段,没有指定的时候,一般默认的是DS 段,SS段是栈段寄存器,专门用来管理程序栈。

  e. IP(Instrcution Pointer)是指令指针寄存器,它只和CS一起使用,而且只有处理器才能直接改变他的内容,当一段代码开始执行时,CS指向代码段的起始地址,IP则指向段内偏移。这样,由CS和IP共同形成逻辑地址。并由总线接口部件转换成物理地址来获得指令。然后,处理器会自动根据当前指定的长度来改变IP的值,使它指向下一条指令。

  f. 访问内存单元时,处理器也会将数据段寄存器(DS,ES或者SS)和偏移地址相加,得到访问内存所需要的物理地址。

      5.  Intel 8086处理器的内存分段机制

  a. 8086的段寄存器和IP寄存器都是16位的,如果直接把段地址和偏移地址相加,只能得到16位的地址,但是16位的物理地址只能访问64KB的内存,这个实在是太小了,所以8086有20根地址线,可以提供20位的物理地址。

  b. 8086在形成物理地址时,先将段寄存器的内容左移4位(相当于乘以十六进制的10,或者十进制16),形成20位的段地址,然后再同16位的偏移地址相加,得到20位的物理地址。比如,对于逻辑地址F000H:052DH,处理器在形成物理地址的时候,将段地址F000H左移4位,变成F0000H,再加上偏移地址052DH,就形成了20位的物理地址F052DH。

  c. 这样,8086就可以访问1MB的内存内容了,在段不重叠的情况下,最多可以将1MB的内存分成65536个段,每个段正好是16字节,也可以把段的长度扩大,段最大的长度是64KB(偏移地址是16位的),最多能分16个段,8086分配段地址时,一定要保证段地址是可以被十六进制的10,或者十进制16整除,否则就不能形成有效的偏移地址。也就是说,8086的逻辑分段是16字节对齐的。这个在以后写段编程的时候会体会到。

★PART3:基本输入输出系统,硬盘

  1. 计算机的加电和复位

  a. 在处理器的引脚中,有一个是RESET,用于接受复位信号,每当处理器加电,或者RESET引脚的电平由低变高的时候,处理器都会执行一个硬件初始化,以及一个可选的内部测试(Biuld-in Self-Test,BIST),然后将内部所有寄存器初始化到一个预置的状态。比如8086在初始化的时候,CS的内容会变为0xFFFF,其他寄存器的内容都是0x0000,包括IP。

  b. 内存的每个比特的储存都是靠一个极其微小的晶体管,外加一个同样极其微小的电容组成的,这样微小的电容的漏电速度会非常快,所以内存需要定期补充电荷,补充电荷的过程称为刷新,这种储存器也成为动态随机访问储存器(Dynamic Random Access Memory,DRAM)。在内存上访问任何一个内存单元的速度和它的位置无关,这称为随机访问。内存刷新的时候,处理器将无法访问它,内存断电后,其保存的内容都会消失,所以每当处理器加电的时候,它无法从内存中获得任何指令。

      2. 基本输入输出系统(BIOS)

  a.  Intel 8086可以访问1MB的内存,这1MB可访问区域被划分为几个区域,其中大部分用来访问内存条(DRAM,地址0x00000-0x9FFFF,一共640KB),剩余部分给了只读存储器(ROM,地址0xF0000-0xFFFFF)和外围的板卡,只读存储器(Read Only Memory,ROM)不需要刷新,内容是预先设定的,断电了也不会消失,也很难改变(不可擦写)。处理器每次加电后都会自动执行这一个区域的代码因为8086加电或者复位的时候,CS=0xFFFF, IP=0x0000,所以取的第一条指令位于物理地址0xFFFF0,刚好是ROM的区域。

  b. 处理器的执行指令的顺序是从内存的低地址到高地址,如果从0xFFFF0开始执行,那么这个位置距离1MB内存的顶端(物理地址0xFFFFF)只有16个字节的长度,一旦IP寄存器的值超过0x000F,比如为0x0011,那么它与CS一起形成的物理地址因为溢出而变成0x00001,绕回1MB内存的最低端。所以在位于物理地址0xFFFF0的地方,一般是一个跳转指令,使处理器在ROM较低的位置处开始执行指令。

  c.  ROM芯片的内容包括很多部分,主要是对硬件的诊断,检测和初始化。他还可以提供一套软件例程(也就是后面要说到的BIOS中断),让人们不必了解硬件细节的情况下从外围设备(比如键盘)获得输入数据,或者向外围设备(比如显示器)输出数据,这块ROM芯片只针对那些最基本的,而又最重要的设备,它所提供的软件例程也只包含最简单,最常规的功能。所以这块芯片又叫基本输入输出系统(Base Input & Output System,BIOS)ROM。(正确的理解应该是ROM是一块芯片,上面搭载了BIOS,而BIOS又可以对其他设备进行参数设置,比如CMOS RAM。)

       3. 硬盘的基本构造和其工作原理

  a. 软盘,光盘,硬盘,U盘这些设备被称为是“外存”(外存储器)。软盘(Floppy Disk)一块以塑料作为基片,上面涂磁性物质来记录数据的一个设备。硬盘(Hard Disk,HDD)的记录数据方式与软盘很像,也是由磁性物质来记录数据的,不过硬盘是多盘片,密封,高转速的,采用铝合金作为基片,并且在表面涂上磁性物质来记录二进制数据的一个存储设备。

  

 

  d. 硬盘可以有多个盘片,也可以只有一个(单碟),这些碟片都是共轴的,由电机带动转动,可以打到每分钟3600转或者7200转,甚至上万转(转/分钟,Round Per Minute,RPM)。每个盘片都有两个磁头(Head),上面一个,下面一个,所以经常用磁头来代指盘面。磁头都编号,第一个盘片的而上面磁头编号是0,下面编号是1,第二个盘片上磁头编号是2,下磁头编号是3,依次类推。每个磁头通过磁头臂固定在一个支架上,由步进电机带动着在一起在盘片的中心和边缘来回移动。盘片高速转动的时候,磁头每步进一次,都会绕着圆心在盘面上“画”出一个看不见的圆圈,这就是磁道(Track)。

  e. 磁道是记录数据的轨迹,每个盘面上的磁道可以形成一个虚拟的圆柱,称为柱面(Cylinder)。磁道或者柱面从最边缘往圆心方向开始从0开始编号。柱面是用来优化读写的,因为移动磁头是一个机械动作,对于处理器来说是很慢的一个操作,这就是所谓的寻道,所用的时间被叫做寻道时间。为了加速读写,最好的办法是尽量不移动磁头,所以当0面的磁道不足以容纳所写入的数据,应当把剩余的部分写在1面的同一磁道上,如果还写不下,就写到2面的同一磁道上,也就是硬盘上的数据访问是以柱面来组织的。

  f. 磁道还可以进一步划分为扇区(Sector)。磁道占据一定的宽度,把他划分为很多个区域后,这些区域就会呈现扇形,所以这就是扇区名字的由来,通常硬盘的每个磁道都会被划分为63个个扇区,每个扇区都有一个编号,但是扇区的编号是由1开始的,扇区与扇区之间用空白间隙隔开,每个扇区头开始,然后是512个字节的占据区,每个扇区头都包含着每个扇区自己的信息,主要有本扇区的磁道号,磁头号和扇区号,用来硬盘定位机构使用。现代的硬盘在扇区头加一个指示扇区是否健康的标志,以及用来替换该扇区的扇区地址,用于替换扇区的,是一些保留和隐藏的磁道。

      4. 主引导扇区(MBR)

  a. 在大多数情况下,ROM-BIOS会从硬盘的某个位置读取更多的指令加载到内存供处理器读取,让处理器跳出ROM的区域。这个扇区是硬盘的第一个扇区(0面0道1扇区,或者0头0柱1扇区),也就是主引导扇区(MBR),ROM-BIOS将会读取硬盘主引导扇区的内容,将其加载到内存的0x0000:0x7c00处,然后用一个jmp指令跳转到这个地方执行。

  b. 为什么要使用0x0000:0x7c00这个地址?其实这是有原因的。

  来源https://www.zhihu.com/question/34652343/answer/59621850作者:薛磊,链接:来源:知乎,著作权归作者所有。

  操作系统或是bootloader开发者必须假设 他们的汇编代码被加载并从0x7C00处开始执行。0x7C00的定义对于这个地址,它不属于Intel x86平台规范的,而是属于BIOS规范中定义的内容。0x7C00第一次出现在IBM PC 5150的BIOS处理int 19(19号中断)的时候,IBM PC 5150是x86(32位)IBM PC/AT系列的祖先,这款PC于1981年发布,使用了intel 8088(16位)的处理器和16KB的RAM内存,BIOS和微软的基本指令均放在该内存中。当打开电源,BIOS开始自检,然后出发19号中断,在处理19号中断时,BIOS检测电脑是否具有软盘、硬盘或是固定磁盘,如果有任何可以使用的磁盘,BIOS就把磁盘的第一个扇区(512B)加载到内存的0x7C00地址处。

  0x7C00的前身 0x7C00地址第一次出现在IBM PC 5150的ROM BIOS中,在此之前使用的地址是0x200。使用该地址的原因主要有:当时8086中断向量使用地址为0x0-0x3FF;86-DOS从0x400处被加载;而它不使用0x200-0x3FF这段中断向量地址。因此这段0x200-0x3FF地址不能被其他程序使用,Tim Paterson(86-DOS开发者)选择0x200作为MBR加载地址。

      0x7C00的意义他们想留下32kb内更多的空间给操作系统来加载自己;8086/8088使用0x0-0x3FF作为中断向量,然后BIOS数据紧随之后;引导扇区是512字节,但是用于引导程序的栈或数据区域需要多于512 字节;因此0x7C00,32kb中的最后1kb被选中。一旦操作系统被引导并开始,引导扇区将一直不会被使用指导重启,因此操作系统和应用程序可以自由的使用32KB的最后1kb空间。

       在操作系统被加载后,内存布局如下:   

转载于:https://www.cnblogs.com/Philip-Tell-Truth/p/5184812.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值