x86汇编语言基础

硬件知识
  • 处理器进行计算的原理,将数据传送给寄存器A和B,然后计算单元ALU计算出来传送给其他寄存器或者覆盖A或B在这里插入图片描述
  • 为了访问内存,处理器需要给出一个地址,访问包括读和写,处理器还要指明,本次访问是读访问还是写访问,如果是写访问,则还要给出待写入的数据
  • 尽管内存的最小组成单位是字节,但是,经过精心的设计和安排,它能够按字节,字,双字和四字进行访问
  • 仅通过单次访问就能处理8位,16位,32位或者64位的二进制数。注意是单次访问
  • 对于Intel处理器来说,如果访问内存中的一个字,那么,它规定高字节位于高地址部分,,低字节位于低地址部分,这称为低端字节序
指令
  • 指令和非指令的普通二进制数是一模一样的,在组成内存的电路中,都是一些高低电平的组合
  • 因为处理器是自动按顺序取指令并加以执行的,在指令中混杂非指令的数据会导致处理器不能正常工作
  • 因此,指令和数据要分开存放,分别位于内存中的不同区域,存放指令的区域叫代码区,存放数据的区域叫做数据区
  • 并非每一个二进制数都代表着一条指令,每种处理器在设计的时候,也只能拥有有限的指令,一个处理器能够识别的指令的集合,称为该处理器的指令集
  • 对处理器来说,指令的操作码隐含了如何执行该指令的信息,比如它是做什么的,以及怎么去做
  • 处理器的设计者用某些数来指示处理器所进行的操作,这称为指令
  • 注意字数据在内存中的存放特点,地址0001H和0002H里的内容分别是5D和00,如果按字读,就是005DH,如果按字节读,就是5D,00
8086通用寄存器
  • 8086处理器内部有8个16位的通用寄存器,分别被命名为AX,BX,CX,DX,SI,DI
  • 这8个寄存器都是16位的,所以通常用于进行16位的操作
  • 这8个寄存器中的前4个,即AX,BX,CX,DX,又各自可以拆分成两个8位的寄存器来使用,总共可以提供8个8位的寄存器,AH,AL,BH,BL,CH,CL,DH,DL
  • 这样一来,当需要在寄存器和寄存器之间或者寄存器和内存单元之间进行8位的数据传送或者算术逻辑运算时就很方便
    在这里插入图片描述
重定位问题
  • 在x86汇编语言基础中又讲述了一遍重定位的问题
  • 在我的博客可重定位文件中有过讲述,不过这本书的讲解更加认真细致,强烈建议大家都来读一遍
  • 为了在硬件一级提供对段地址:偏移地址内存访问模式的支持,处理器至少要提供两个段寄存器,分别是代码段【Code Segment】CS寄存器,和数据段【Data Segment】DS寄存器
  • 对CS内容的改变将导致处理器从新的代码段开始,在开始访问内存中的数据之前,也必须首先设置好DS寄存器,使之指向数据段
  • 当处理器访问内存时,它把指令中指定的内存地址看成是段内的
    偏移地址,而不是物理地址。这样,一旦处理器遇到一条访问内存的指令,它将把 DS 中的数据段起始地址和指令中提供的段内偏移相加,来得到访问内存所需要的物理地址
    在这里插入图片描述
  • 8086 内部有 4 个段寄存器。其中, CS 是代码段寄存器DS 是数据段寄存器, ES 是附加
    段(Extra Segment)寄存器
    。附加段的意思是,它是额外赠送的礼物,当需要在程序中同时使
    用两个数据段时, DS 指向一个, ES 指向另一个。可以在指令中指定使用 DS 和 ES 中的哪一
    个,如果没有指定,则默认是使用 DS。 SS 是栈段寄存器,以后会讲到,而且非常重要
  • IP 是指令指针(Instruction Pointer)寄存器,它只和 CS 一起使用,而且只有处理器才能直
    接改变它的内容
    。当一段代码开始执行时, CS 指向代码段的起始地址, IP 则指向段内偏移。
    这样,由 CS 和 IP 共同形成逻辑地址,并由总线接口部件变换成物理地址来取得指令。然后,
    处理器会自动根据当前指令的长度来改变 IP 的值,使它指向下一条指令
  • 如果在指令的执行过程中需要访问内存单元,那么,处理器将用 DS 的值和指令中
    提供的偏移地址相加,来形成访问内存所需的物理地址。

    在这里插入图片描述
地址容量运算
  • 1000是 2 3 2^{3} 23
  • 如果是20位地址线,0xFFFFF表示 2 20 − 1 2^{20}-1 2201 ,再加上0表示的一个地址,是 2 20 2^{20} 220个地址即1048576 byte = 1M的内存大小
  • 举个例子来说,左移四位相当于将16进制的数字乘以16进制的10,计算物理地址是[CS:IP],偏移地址都是从0开始的,所以CS必须能够被16整除
  • 因此地址都是16的倍数
  • 两种极端情况,段是连续的,且互相不重叠的情况下
  • 最多可以分为,段地址16位可以分为0X 0000——0xFFFF,每一个段16个字节,段内偏移0x0000——0x000F,一共65536个段
  • 最少可以分为16个段,因为段内偏移是16位的,所以最大空间为 2 16 2^{16} 216 = 64kb,因此每个段的起始地址是0000,1000, 2000,F000
  • 同一个·物理地址可以随意指定一个段来访问它,前提是那个物理地址位于该段的64kb范围内,同一个物理地址,实际上对应着多个逻辑地址
练习题
  • 数据段寄存器 DS 的值为25BCH 时,计算 Intel 8086可以访问的物理地址范围。
  • 因此,范围是25BC:0000——25BC:FFFF,即25bc0—— 35BBF这就是物理地址范围
汇编语言
  • 汇编语言(Assembly Language)
NASM编译器
  • 理论上,不管用的是什么操作系统, Windows 也好, DOS 也好, Linux 也好,只要是针对Intel 处理器开发的软件,底层的机器指令代码都是相同的,没有理由说某个软件只能在
    Windows 操作系统上运行,而不能在 Linux 上运行
  • 事实上,仅仅具有一致的底层机器代码还远远不够。别忘了,这些代码要被处理器来依次
    执行,首先需要加载到内存并实施重定位。在这种情况下,除了那些真正用于做事的机器指令
    之外,软件还需要一些额外的信息来告诉操作系统,如何加载自己。更有甚者, Windows 会建议为它开发的软件应当包含一些图标或者图片。这就是为什么每个 Windows 软件都会显示一个图标的原因。在这种情况下,因为每种操作系统都会根据自身的工作特点,定义自己所能识别的软件可执行文件格式,而缺乏通用性,尽管在这些软件里,真正用于计算 5+6 的机器指令都一模一样
接力机制
  • 当按下电脑的重启键之后,cpu会完全重置寄存器,在这些寄存器里面,除了CS被设置为0x FFFF 外全部被置为0X 0000
  • 这时候内存还没有完全初始化,可是cpu已经要在脉冲的作用下开始读取指令了
  • 所以cpu会读取ROM【只读寄存器】里面已经预先存好的程序指令,这些程序的作用是进行一些初始化,检测的作用。也会封装一些对基本硬件的访问程序,所以称为BIOS【基本输入输出系统】
  • ROM的内容不会随着断电而消失,是持久存在的
  • 当BIOS执行完毕后,会将硬盘里面的 0柱面0磁道1扇区的内容加载到内存当中0x0000:0x7c00当中也就是0x07c000,而且还会检测末尾的两个字节是否是0x55,0xAA,如果是这两个字节,就说明主引导扇区有效
  • 在加载完后就会进行一个跳转,跳转到该程序的起始指令地址开始执行,而这个程序也是一个接力程序,他是操作系统的自加载程序,会把操作系统的剩余部分不断加载到内存当中
  • 虚拟机的硬盘其实是一个文件,这个虚拟硬盘文件有很多格式,每家虚拟机公司都制定了各自的格式
  • 微软的虚拟机虚拟硬盘格式是VHD
  • 所以我们只需要将操作系统的自加载程序写入第一个扇区,程序就会自动执行
  • LBS,当我们要像硬盘读写数据的时候,需要设置柱面,磁道,扇区,这是很麻烦的事情,LBS是从硬件上提供的功能,将硬盘组织为一个线性的块存储机构,我们只需要指定第n个扇区即可,这个n会被自动解析为对应的柱面,磁道和扇区
  • 硬盘的读写是以扇区为最小单位的。所以,无论什么时候,要从硬盘读数据,或者向硬盘写数据,至少得是 1 个扇区。
显卡
自我总结
  • 显示屏由显卡控制,显卡上有显存
  • 显卡会不断的读取显存里面的数据,将其显示到屏幕上。
  • 而显卡本身会有很多种不同的显示模式,这些不同的模式决定了对于显存中的字节数据如何进行解析,所以在系统初始化的时候,要进行显卡模式的设置
字符模式
  • 而显卡的默认设置是字符模式,两个字节显示一个字符,第一个字节是该字符的 ASCII码,第二个字节是该字符的显示模式,前四位是背景色的设定KRGB,K是是否闪烁的意思,RGB就是颜色, IRGB是后四位是前景色的设定,I是是否高亮的意思
  • 字符模式是在硬件上提供了支持,当选择了这种模式后,第一个字节的ASCII码通过一个字符解析装置,显示在屏幕上
  • 在这种模式下,显存从低地址到高地址的字节依次对应屏幕上的从上到下从左到右的位置
  • 为了能够让CPU直接往显存中写入数据,硬件上将显存的存储空间映射为地址空间中的一段连续地址。
  • 显卡控制显示器的最小单位是像素,一个像素对应着屏幕上的一个点
图形模式
  • 显存的第 1 个字节对应着屏幕左上角连续的 8 个像素;第 2 个字节对应着
    屏幕上后续的 8 个像素, 后面的依次类推。
  • 显卡的工作是周期性地从显存中提取这些比特,并把它们按顺序显示在屏幕上
地址分布
  • 所以8086的1M寻址空间的分布如下图所示,一部分是ROM,一部分是映射到硬件上面,剩下的内存条
  • 8086 可以访问 1MB 内存。其中, 0x00000~9FFFF 属于常规内存,由内存条提供; 0xF0000~0xFFFFF 由主板上的一个芯片提供,即 ROM-BIOS。中间还有一个 320KB 的空洞,即 0xA0000~0xEFFFF。传统上,这段地址空间由特定的外围设备来提供,其中就包括显卡。因为显示功能对于现代计算机来说实在是太重要了。
  • 由于历史的原因,所有在个人计算机上使用的显卡,在加电自检之后都会把自己初始化到80×25 的文本模式。在这种模式下,屏幕上可以显示 25 行,每行 80 个字符,每屏总共 2000 个字符。
  • 0xB8000~0xBFFFF 这段物理地址空间,是留给显卡的,由
    显卡来提供,用来显示文本。
  • 考虑到文本模式下显存的起始物理地址是 0xB8000,这块内存可以看成是段地址为0xB800,偏移地址从 0x0000 延伸到 0xFFFF 的区域,因此我们可以把段地址定为0xB800
    在这里插入图片描述
声明数据
  • 要放在程序中的数据是用 DB 指令来声明(Declare)的, DB 的意思是声明字节(Declare Byte),
    所以,跟在它后面的操作数都占一个字节的长度(位置)。注意,如果要声明超过一个以上的数据,
    各个操作数之间必须以逗号隔开。
    除此之外, DW(Declare Word)用于声明字数据, DD(Declare Double Word)用于声明
    双字(两个字)数据, DQ(Declare Quad Word)用于声明四字数据。 DB、 DW、 DD 和 DQ 并
    不是处理器指令,它只是编译器提供的汇编指令,所以称做伪指令(pseudo Instruction)。 伪指
    令是汇编指令的一种,它没有对应的机器指令,所以它不是机器指令的助记符,仅仅在编译阶
    段由编译器执行,编译成功后,伪指令就消失了,所以在程序执行时,伪指令是得不到处理器
    光顾的,实际上,程序执行时,伪指令已不存在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值