读笔 汇编语言-基于Linux环境(第4章-位置:寄存器、内存寻址以及了解数据存储位置II)

文章也同时在简书更新

引言

本篇文章继续第四章关于内存寻址的探讨,主要介绍各类寄存器。

摘要

16位和32位段寄存器

不管CPU正在做什么,只要他对内存中某一个位置进行寻址,那么该位置的段地址就会出现在6个寄存器之一中。

所有的段寄存器大小都是16位所有的段寄存器大小都是16位!!所有的段寄存器大小都是16位!!!无论CPU是什么型号,甚至是对于32位CPU来说也是如此。

  • CS(code segment)代码段机器指令存放在代码段的某些偏移位置处。CS包含当前执行指令的代码段的段地址。
  • DS(data segment)数据段变量和其他数据存放在数据段的某些偏移位置处。也许会有很多个数据段,但CPU一次只能使用一个,这是通过将该段的段地址放入寄存器DS来实现的。
  • SS(stack segment)堆栈段:堆栈式CPU用来暂时存放数据和地址等一个非常重要的部件。堆栈也有一个段地址,它存放在SS中。
  • ES(extra segment)附加段:它是一个可用于指定内存中某一位置的备用段
  • FSGS是ES的克隆:从命名上可以联想到E->F->G

通用寄存器

  • 段寄存器是存放段地址的专家,通用寄存器则用来存放偏移地址,它必须和段地址成对出现,以标识内存中的某个位置。
  • 在当前32位世界中,通用寄存器分为三个一般类:16位通用寄存器,32位扩展通用寄存器和8位的半寄存器。16位和8位寄存器实际上是32位寄存器内部的一块区域的名字。
  • 32位通用寄存器的高16位根本没有自己的名字,可以通过SI来访问ESI的低16位,但是想要获取高16位,必须要引用ESI,获取整个32位数据。

半寄存器

  • 8位半寄存器的好处是可以读取和修改16位数据的其中一半,高H低L。但这一双重特性只涉及16位通用寄存器AXBXCXDX。其他的16位通用寄存器(SPBPSIDI)并不具有类似的特性。例如,不存在名为SIH和SIL的8位寄存器。

指令指针寄存器

  • 指令指针寄存器(instruction pointer)通常称为IP,它是16位的大小。在32位保护模式下,则为EIP
  • 它只做一件事情:包含当前代码段中下一条即将执行的机器指令的偏移地址。一个程序可能有很多个代码段或者只有一个。当前代码段(current code segment)是指段地址当前存放在代码寄存器CS中的那段代码。
  • 当执行程序时,CPU使用IP来跟踪位于当前代码段中的位置。每执行一条指令后,IP就递增一定数量的字节。这个字节数是刚刚执行的那条指令的大小。最终的结果是IP跳到了内存中更远的地方,指向下一条即将执行的指令的开始位置。
  • CS和IP一起,保存下一条即将执行指令的完整地址。在实模式段模型中,CS和IP共同组成一个20位的地址,指向实模式内存中的1048576(2的20次方)个字节之一。
  • 值得注意的是,IP是唯一既不能直接读出,也不能直接写入的寄存器。有一些技巧可以用来获取当前IP寄存器的值,但是拥有IP的值并不是像你想象得那么有用。

标志寄存器

  • 标志寄存器(flags register)在8086,8088和80286中的大小为16位,正式名称是FLAGS。在386等更高CPU中,它的大小是32位,正式名称为EFLAGS
  • 当程序执行测试时,它所测试的就是标志寄存器中某个单个的标志位。因为每个标志位可以包含的值只有0或1,所以在汇编中,测试就是二选一的过程:标志位被设置为1,或者没有被设置为1。根据是否被设置为1,程序会执行非此即彼的不同决策,走不同的路。关于各标志位的具体作用将在后续再详细介绍。

感想

如果整个PC是一个工厂车间,各类外设是工人们,那么CPU就是车间工长,而寄存器就是工长衣服的口袋,里面装着他常用的各种数据和信息。工人们和工长在名为“数据总线”的流水线上协同工作,保障车间的正常运作。

周鶏🐣(Kimiko) wechat
拿起手机扫一扫,欢迎关注我的个人微信公众号:「洛斯里克的大书库」。
坚持原创技术分享,您的支持将鼓励我继续创作!