大道至简 -> 汇编语言(二)

作者:少聪 github &&掘金

寄存器 、 通用寄存器以及字在寄存器中的存储

  • CPU 是运算器、控制器、寄存器(CPU工作原理)等器件构成,靠内部总线链接

    • 运算器进行信息处理
    • 寄存器进行信息存储
    • 控制器控制各种器件进行工作
    • 内部总线连接各种器件,在它们之间进行数据传送
  • 不同的 CPU 寄存器的个数、结构是不相同的。

    比如 8086CPU 有 14个寄存器 : AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。

  • 通用寄存器

    • 8086CPU 的所有寄存器都是16位的。 可以存放两个字节

    • AX、BX、CX、DX 这4个寄存器通常就是存放一般性的数据,被称为通用寄存器。

  • 16 位寄存器分成 2 个8 位寄存器

    AX 可分为 AH 和 AL

    BX 可分为 BH 和 BL

    CX 可分为 CH 和 CL

    DX 可分为 DH 和 DL

  • 16 位寄存器 分为 两个 8 位寄存器(高 8 位 和 低 8 位)

高8位和低8位

如上图所示:AX 的低 8 位(0~7 位)构成了 AL 寄存器

高 8 位(8~15 位)构成了 AH 寄存器。 AH 和 AL 寄存器是可以独立使用的 8 位寄存器。

详细的寄存器对比图

  • 一个字是由两个字节组成,分别为 高位字节 和 低位字节。

  • 任何数据到了计算机中都是以二进制的形式存放的。但是为了方便阅读或者其它,所以又经常用其他的进制来表示。

    比如:二进制一个数值:0100111000100000

    ​ 十六进制:4E20

    ​ 十进制:20000

    • 几条汇编指令
  • 汇编指令是控制 CPU 进行工作。

汇编指令举例

  • 物理地址

    • CPU 访问内存单元时,需要给出内存单元的地址。所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,我们将这个唯一的地址称为物理地址。

    • CPU 具有下面几方面的结构特性

    • 运算器一次最多可以处理 16 位的数据

    • 寄存器的最大宽度为 16 位
    • 寄存器和运算器之间的通路为 16 位

    • 8086CPU 给出物理地址的方法

    • 8086CPU 有 20 位地址总线,可以传送 20 位地址,达到 1MB 寻址能力。8086CPU 又是 16 位结构,在内部一次性处理、传输、暂时存储的地址为 16 位。从 8086CPU 的内部结构来看,如果将地址从内部简单地发出,那么它只能送出 16 位的地址,表现出的寻址能力只有 64KB。

    • 8086CPU 采用一种在内部用两个 16 位地址合成的方法来形成一个 20 位的物理地址。

    • 8086CPU 相关部件的逻辑图如下

8086CPU 相关逻辑图

  当 8086CPU 要读写内存时:

  1、CPU 中的相关部件提供两个 16 位的地址,一个称为段地址,另一个称为偏移地址。

  2、段地址和偏移地址通过内部总线送入一个称为地址加法器的部件。

  3、地址加法器将两个 16 位地址合成一个 20 位的物理地址。

  4、地址加法器通过内部总线将 20 位物理地址送上地址总线。

  5、输入输出控制电路将 20 位物理地址送上地址总线。

  6、20 位物理地址被地址总线传送到存储器。

  地址加法器 采用 物理地址=段地址X16+偏移地址 的方法用段地址和偏移地址合成物理地址。

  地址加法器的工作过程如图所示:

地址加法器工作过程

- 段地址

  这里的 “段” 并不是说内存被划分成了一个一个的段,每一个段都有一个段地址。

  内存并没有分段, 段的划分来自于 CPU,比如 8086CPU 用的是 段地址X16+偏移地址 这种方式来给出内存单元的物理地址, 所以我们才用分段的方式来管理内存。

- 段寄存器

  什么部件提供段地址?

  8086CPU 有 4 个段寄存器:CS、DS、SS、ES。

- CS 于 IP

  CS 和 IP 是 8086CPU 中最关键的寄存器,它们指示了 CPU 当前要读取指令的地址。

  CS 为代码段寄存器,IP 为指令指针寄存器。

  也可以这样表述:8086 机中,任意时刻,CPU 将CS:IP 指向的内容当做指令执行。

8086PC 读取和执行指令的相关部件

  上图是 8086PC 读取和执行指令的相关部件

  1、8086CPU 当前状态:CS 中的内容为 2000 ,IP中的内容为 0000

  2、内存 20000~20009 单元存放着可执行的机器码

  3、内存 20000~20009 单元中存放的机器码对应的汇编指令如下

  地址:20000~20002,内容:B8 23 01  长度: 3Byte, 对应汇编指令:mov ax,0123

  地址:20003~20005,内容:BB 03 00  长度: 3Byte, 对应汇编指令:mov bx,0003

  地址:20006~20007,内容:89 D8  长度: 2Byte, 对应汇编指令:mov ax,bx

  地址:20008~20009,内容:01 D8  长度: 2Byte, 对应汇编指令:add ax,bx

- 在内存中,指令和数据没有任何区别, 都是二进制信息, CPU在工作的时候把有的信息看作指令,有的信息看作数据。 那么什么信息被看作指令?

  可以这样认为:CPU 将 CS:IP 指向的内存单元中的内容看作指令,因为,在任何时候,CPU 将 CS、IP 中的内容当作指令的段地址和偏移地址,用它们合成指令的物理地址,到内存中读取指令码、执行。

- 修改 CS、IP 的指令

  为什么修改 CS 、IP 指令? 修改了有什么用?

  在 CPU 中,程序员能够用指令读写的部件只有寄存器,程序员可以通过改变寄存器中的内容实现对 CPU 的控制。

  CPU 从何处执行指令是由 CS、IP 中的内容决定的,程序员可以通过改变CS、IP中的内容来控制 CPU 执行目标指令。

  ​

  如何修改 CS、IP 的值呢?

  当然,8086CPU 必须提供相应的指令,比如 我们如何修改 ax 中的值?,  mov ax,123 这样就将 ax 中的值设为了 123。当然还可以修改其它值, mov 指令被称为 传送指令。

  但是,mov 指令不能用于设置 CS、IP 的值,因为 8086CPU 没有提供这样的功能。而是另外的指令:jmp 指令。

  若想同时修改 CS、IP 的内容, 可以用 jmp 段地址:偏移地址 的指令完成

  jmp 2AE3:3,执行后:CS=2AE3,IP=0003, CPU 将从 2AE33 处读取指令。

  jmp 3:0B16 ,执行后:CS=0003,IP=0B16,CPU将从00B46 处读取指令。

  jmp ax,在含义上好似:mov IP,ax(这只是为了方便理解记忆,而不是说真有这样的指令)。 用寄存器中的值修改 IP。
  • 代码段

    • 8086PC 机在编程时,可以根据需要,将一组内存单元定义为一个段。

    mov ax,0000 (B8 00 00) add ax,0123 (05 23 01) mov bx,ax (8B D8) jmp bx (FF E3)

    这段长度为 10 个字节的指令,存放在 123B0~123B9 的一组内存单元中,我们可以认为,123B0~123B9 这段内存是用来存放代码的,是一个代码段, 它的段地址为 123B,长度为 10 个字节。

    这个是我们在编程时的一种安排, CPU 并不会因为我们这样想的就自动来执行,而是需要我们用代码执行, 因为 CPU 只认被CS:IP 指向的内存单元中的内容为指令, 所有, 要让 CPU 执行我们放在代码段中的指令, 必须要将 CS:IP 指向所定义的代码段中的第一条指令的首地址, 可设 CS=123B、IP=0000。

    • 小总结:

    1、段地址在 8086CPU 的段寄存器中存放。当8086CPU 要访问内存时,由段寄存器提供内存单元的段地址。8086CPU 中有 4 个段寄存器,其中 CS 用来存放指令的段地址。 2、CS 存放指令的段地址,IP 存放指令的偏移地址。 8086 机中,任意时刻,CPU 将 CS:IP 指向的内容当作指令执行。 3、8086CPU 的工作过程: ① 从 CS:IP 指向的内存单元读取指令,读取的指令进入指令缓冲器 ② IP 指向下一条指令 ③ 执行指令。(转到步骤①,重复这个过程。) 4、8086CPU 提供转移指令修改 CS、IP 的内容。

QQ技术交流群:214541576

微信公众号:shavekevin

热爱生活,分享快乐。好记性不如烂笔头。多写,多记,多实践,多思考。

comments powered by Disqus