汇编语言学习笔记 - 第二章

第 2 章 寄存器

  • 一个典型的 CPU 由运算器、控制器、寄存器等器件构成,这些器件靠内部总线相连。
  • 内部总线实现 CPU 内部各个器件之间的联系,外部总线实现 CPU 和主板上其他器件的联系。
  • 在 CPU 中:
    • 运算器进行信息处理;
    • 寄存器进行信息存储;
    • 控制器控制各种器件进行工作;
    • 内部总线连接各种器件,在它们之间进行数据的传送。
  • 寄存器是 CPU 中可以用指令读写的部件,通过改变各种寄存器中的内容来实现对 CPU 的控制。
  • 不同 CPU,寄存器的个数、结构是不相同的。
  • 8086CPU 有 14 个寄存器,分别是:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW。

2.1 通用寄存器

  • 8086CPU 的所有寄存器都是 16 位的,可以存放两个字节。
  • 通用寄存器为 AX,BX,CX,DX,通常用来存放一般性的数据。

举例:以 AX 为例,寄存器的逻辑结构如下图:
在这里插入图片描述

由于兼容上一代 8 位寄存器,8086CPU 的 AX,BX,CX,DX 这 4 个寄存器都可分为两个可独立使用的 8 位寄存器来用:

  • AX 可分为 AH 和 AL;
  • BX 可分为 BH 和 BL;
  • CX 可分为 CH 和 CL;
  • DX 可分为 DH 和 DL;

举例:
在这里插入图片描述

以 AX 为例,8086CPU 的16位寄存器分为两个 8 位寄存器的情况如下图。
在这里插入图片描述

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

举例:
在这里插入图片描述

2.2 字在寄存器中的存储

  • 字节:记为 byte,一个字节由 8 个 bit 组成,可以存在 8 位寄存器中。
  • 字:记为 word,一个字由两个字节组成,分为高位字节和低位字节。
    在这里插入图片描述

在这里插入图片描述在这里插入图片描述

2.3 几条汇编指令

  • 通过汇编指令控制 CPU 进行工作。

举例:在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
指令执行后 AX 中的数据是多少?
程序段中的最后一条指令 add ax , bx ,在执行前 ax 和 bx 中的数据都为 8226H ,相加后所得的值为: 1044CH ,但是 ax 为 16 位寄存器,只能存放 4 位十六进制的数据,所以最高位的 1 不能在 ax 中保存, ax 中的数据为: 044CH 。

在这里插入图片描述
指令执行后 AX 中的数据是多少?
程序段中的最后一条指令 addax , bx ,在执行前 ax 和 bx 中的数据都为 8226H ,相加后所得的值为: IO44CH ,但是 ax 为 16 位寄存器,只能存放 4 位十六进制的数据,所以最高位的 l 不能在 ax 中保存, ax 中的数据为: 044CH 。


注意, al 是作为一个独立的 8 位寄存器来使用的,和 ah 没有关系,CPU 这条指令时认为 ah 和 al 是两个不相关的寄存器。不要错误地认为,诸如 add al , 93H 的指令产生的进位会存储在 ah 中,add al , 93H 进行的是 8 位运算。
如果执行 add ax, 93H ,低 8 位的进位会存储在 ah 中, CPU 在执行这条指令时认为只有一个 16 位寄存器 ax ,进行的是 16 位运算。指令 add ax , 93H 执行后, ax 中的值为: 0158H 。此时,使用的寄存器是 16 位寄存器 ax , add ax, 93H 相当于将 ax 中的 16 位数据 00c5H 和另一个 16 位数据 0093H 相加,结果是 16 位的 0158H 。

在进行数据传送或运算时,要注意指令的两个操作对象的位数应当是一致的,例如:

mov ax,bx 
mov bx,cx 
mov ax,18H 
mov al,18H 
add ax,bx 
add ax,20000

等都是正确的指令,而:

mov ax,bl (在8位寄存器和16位寄存器之间传送数据)
mov bh,ax (在16位寄存器和8位寄存器之间传送数据)
mov al,20000 (8位寄存器最大可存放值为255的数据)
add al,100H(将一个高于8位的数据加到一个8位寄存器中)

等都是错误的指令,错误的原因都是指令的两个操作对象的位数不一致。

2.4 物理地址

  • 所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,我们这个唯一的地址称为物理地址。
  • CPU通过地址总线送入存储器的,必须是一个内存单元的物理地址。
  • 在CPU向地址 总线上发出物理地址之前,必须要在内部先形成这个物理地址。
  • 不同的CPU可以有不同的形成物理地址的方式。

2.5 16 位结构的 CPU

  • 16 位结构的 CPU 的特性:
    • 运算器一次最多可以处理 16 位的数据。
    • 寄存器的最大宽度为 16 位。
    • 寄存器和运算器之间的通路为 16 位。
  • 内存单位的地址在送上地址总线之前,必须在 CPU 中处理、传输、暂时存放,对于 16 位 CPU ,能一次性处理、传输、暂时存储 16 位的地址。

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

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

8086CPU 相关部件的逻辑结构如图2.6所示。
在这里插入图片描述
如图2.6所示,当8086CPU要读写内存时:
(1) CPU中的相关部件提供两个16位的地址,一个称为段地址,另一个称为偏移地址
(2) 段地址和偏移地址通过内部总线送入一个称为地址加法器的部件;
(3) 地址加法器将两个16位地址合成为一个20位的物理地址;
(4) 地址加法器通过内部总线将20位物理地址送入输入输出控制电路;
(5) 输入输出控制电路将20位物理地址送上地址总线;
(6) 20位物理地址被地址总线传送到存储器。

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

举例:8086CPU要访问地址为123C8H的内存单元,此时,地址加法器的工作过程如图2.7所示(图中数据皆为十六进制表示)。
在这里插入图片描述

在这里插入图片描述

2.7 “段地址 X 16 + 偏移地址 = 物理地址”的本质含义

  • 注意,这里讨论的是 8086CPU 段地址和偏移地址的本质含义,而不是为了解决具体的问题而在本质含义之上引申出来的更高级的逻辑意义。
  • “段地址 X 16 + 偏移地址 = 物理地址”的本质含义是:CPU在访问内存时,用一个基础 地址(段地址 X 16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。
  • 更一般地说,8086CPU 的这种寻址功能是“基础地址 + 偏移地址 = 物理地址”寻址模式的一种具体实现方案。8086CPU 中,段地址 X 16可看作是基础地址。

举例:比如说,学校、体育馆、图书馆同在一条笔直的单行路上(参考图2.8),学校位于路的起点(从路的起点到学校距离是0米)。
在这里插入图片描述
你要去图书馆,问我那里的地址,我可以用两种方式告诉你图书馆的地址:

  1. 从学校走2826m到图书馆。这2826m可以认为是图书馆的物理地址。
  2. 从学校走2000m到体育馆,从体育馆再走826m到图书馆。第一个距离2000m, 是相对于起点的基础地址,第二个距离826m是相对于基础地址的偏移地址(以基础地址为 起点的地址)。

第一种方式是直接给出物理地址2826m,而第二种方式是用基础地址和偏移地址相加 来得到物理地址的。

举例:第二个比喻进一步说明“段地址X16+偏移地址=物理地址”的思想。
我们为上面的例子加一些限制条件,比如,只能通过纸条来互相通信,你问我图书馆的地址我只能将它写在纸上告诉你。显然,我必须有一张可以容纳4位数据的纸条,才能写下2826这个数据。
在这里插入图片描述
可不巧的是,我没有能容纳 4 位数据的纸条,仅有两张可以容纳 3 位数据的纸条 。 这 样我只能以这种方式告诉你2826这个数据。
在这里插入图片描述
在第一张纸上写上 200 (段 地址) ,在第二张纸上写上 826 (偏移地址 ) 。 假设我们事前对这种情况又有过相关的约定:你得到这两张纸后,做这样的运算:200 (段地址) x l0 + 826 (偏移地址) = 2826 (物理地址)。


8086CPU就是这样一个只能提供两张3位数据纸条的 CPU。

2.8 段的概念

  • 其实,内存并没有分段,段的划分来自于CPU,由于8 0 8 6CPU用“基础地址(段地址xl6)+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存。
  • 如图2.9所示,我们可以认为:地址 10000H〜100FFH的内存单元组成一个段,该段的起始地址(基础地址)为 10000H, 段地址为 1000H, 大小为 100H;我们也可以认为地址10000H〜1007FH、10080H〜100FFH的内存单元组成两个段,它们的起始地址(基础地址)为:10000H 和 10080H,段地址为:1000H 和 1008H,大小都为 80H。

在这里插入图片描述

  • 将若干地址连续的内存单元看作一个段,用段地址X 16 定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。
  • 有两点需要注意:
    • 段地址X 16 必然是 16 的倍数,所以一个段的起始地址也一定是 16 的倍数;
    • 偏移地址为 16 位,16 位地址的寻址能力为 64 KB,所以一个段的长度最大为 64 KB。

在这里插入图片描述
在这里插入图片描述

2.9 段寄存器

  • 8086CPU 在访问内存时要由相关部件提供内存单元的段地址和偏移地址址在送入地址加法器合成物理地址。
  • 段地址 8086CPU 的段寄存器中存放。
  • 8086CPU 有 4 个段寄存器:CS 、DS /SS 、 ES 。当 8086CPU 要访问内存时由这 4 个段寄存器提供内存单元的段地址。

2.10 CS 和 IP

  • CS 为代码段寄存器,IP 为指令指针寄存器。
  • 在 8086PC 机中,任意时刻,设CS中的内容为M, IP中的内容为N8086CPU将从 内存MX16+N单元开始,读取一条指令并执行。也可以这样表述:8086机中,任意时刻,CPU 将 CS:IP 指向的内容当作指令执行。

举例:8086CPU 读取、执行指令的工作原理(图中数字均为 16 进制)
在这里插入图片描述
图 2.10 说明如下:
(1) 8086CPU当前状态:CS中的内容为2000H, 1P中的内容为0000H;
(2) 内存20000H〜20009H单元存放着可执行的机器码;
(3) 内存20000H〜20009H单元中存放的机器码对应的汇编指令如下。
地址:20000H〜20002H,内容:B8 23 01,长度:3Byte,对应汇编指令:movax,0123H
地址:20003H〜20005H,内容:BB03 00,长度:3Byte,对应汇编指令:movbjOXXBH
地址:20006H〜20007H,内容:89D8,长度:2Byte,对应汇编指令:movax,bx
地址:20008H〜20009H,内容:01D8,长度:2Byte,对应汇编指令:addax,bx

下面一组图(图2.11~2.19),以图2.10描述的情况为初始状态,展示了 8086CPU 读取、执行一条指令的过程。(隐藏了具体工作细节)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面一组图(图2.20~2.26),以图 2.19 的情况为初始状态,展示了 8086CPU 继续读取、执行 3 条指令的过程,注意 IP 的变化(隐藏了读取每条指令的细节)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过上面的过程展示,8086CPU 的工作过程简要描述如下:
1.从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器;
2. IP=IP+所读取指令的长度,从而指向下一条指令;
3. 执行指令。转到步骤(1),重复这个过程。


在8086CPU加 电 启 动 或 复 位 后( Bp CPU刚 幵 始 工 作 时 )CS和 IP被 设 置 为 CS=FFFFH, IP=0000H,即在8086PC机刚启动时,CPU从内存FFFFOH单元中读取指令 执行,FFFFOH单元中的指令是8086PC机开机后执行的第一条指令。

我们在第1章中讲过,在内存中,指令和数据没有任何区别,都是二进制信息, CPU 在工作的时候把有的信息看作指令,有的信息看作数据。

现在,如果提出一个问题: CPU 根据什么将内存中的信息看作指令?

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

如果说,内存中的 一段信息曾被CPU执行过的话,那么,它所在的内存单元必然被CS:IP指向过。

2.11 修改 CS 和 IP 的指令

  • 在CPU中,程序员能够用指令读写的部件只有寄存器,程序员可以通过改变CS、IP中的内容来控制CPU执行目标指令。
  • mov 指令被称为传送指令,可以修改大部分寄存器中的值,但是不能修改 CS, IP 中的值。
  • jmp 指令被称为转移指令,用于设置CS、IP的值。

举例:若想同时修改CS、IP的内容,可用形如“jmp段地址:偏移地址”的指令完成,如
jmp2AE3:3,执行后:CS=2AE3H,IP=0003H, CPU 将从 2AE33H 处读取指令。
jmp3:0B16,执行后•• CS=0003H, IP=0B16H, CPU 将从 00B46H 处读取指令。

  • “jmp段地址:偏移地址”指令的功能为:用指令中给出的段地址修改CS, 偏 移 地 址修改IP。

举例:若想仅修改 IP 的内容,可用形如 “jmp 某一合法寄存器”的指令完成,如:
jmp ax,指令执行前:ax=1000H,CS=2000H,IP=0003H
指令执行后:ax=1000H, CS=2000H, IP=1000H
jmpbx,指令执行前:bx=0B16H, CS=2000H, IP=0003H
指令执行后:bx=0B16H, CS=2000H, IP=0B16H

  • “jmp 某一合法寄存器”指令的功能为:用寄存器中的值修改IP。
  • jmp ax,在含义上好似:mov IP,ax

举例:内存中存放的机器码和对应的汇编指令情况如下图所示,设 CPU 初始状态; CS = 2000H, IP = 0000H, 写出指令序列。
在这里插入图片描述
## 2.11 修改 CS 和 IP 的指令

2.12 代码段

  • 对于 8086PC 机,在编程时,可以根据需要,将一组内存单元定义为一个段。我们可以将长度为N(N <- 64KB)的一组代码,存在一组地址连续、起始地址为16的倍数的内存单元中。

举例:
在这里插入图片描述

  • CPU只认被CS:IP指向的内存单元中的内容为指令。所以,要让CPU执行我们放在代码段中的指令,必须要将CS:IP指向所定义的代码段中的第一条指令的首地址。
  • 如果要让这段代码得到执行,可设CS=123BH、IP=0000H。

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值