汇编语言笔记第二章

第二章

一个典型的CPU一般由运算器、控制器、寄存器等构成,这些器件靠内部总线相连,相对应的外部总线实现CPU和主板上其他器件的联系。

总的来说,CPU中运算器进行信息处理,寄存器进行信息存储,控制器控制各器件进行工作。

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

2.1 通用寄存器

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

在这里插入图片描述

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

AX =>AH 和 AL BX => BH 和 BL CX => CH 和 CL DX => DH 和 DL
在这里插入图片描述
2.2 字在寄存器中的存储

出于对兼容性的考虑,8086CPU可以一次性处理两种尺寸的数据。

字节:byte,一个字节由8个bit组成,可存放在8位寄存器中

字:word,一个字有两个字节组成,分别为这个字的高位和低位字节。

数字20000存在AX中,AH存储高位字节,AL存储低位字节

寄存器 寄存器中的数据 表示的值
AX 0100111000100000 20000(4E20H)
AH 01001110 78(4EH)
AL 00100000 32(20H)

为了区分不同的进制,16进制后加H,2进制加B,10进制后什么都不加。

2.3 几条汇编指令

在这里插入图片描述
在写汇编指令时不区分大小写

关于溢出,假设ax和bx的数据都为8226H,执行add ax, bx指令,则相加后的值为1044CH,但ax为16为寄存器,所以最高位不保存,ax中的数据为044CH。

假设执行前ax为00C5H,执行add al, 93H,相加后为158H,但al只有8位,所以最终ax的数据为0058H,要注意此时al是作为一个独立的8位寄存器来使用的,它的进位并不会存储在ah中,add al, 93H进行的是8位运算。

在进行数据传送或运算时,要注意指令的 两个操作对象的位数应当是一致的,mov ax, bx mov al, 20000 和 add al, 100H都是错误的。

2.4 物理地址

CPU访问内存单元时,要给出内存单元的地址,所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元都有一个唯一的地址,即物理地址。

在CPU向地址总线发出物理地址之前在内部先形成这个物理地址。

2.5 16位结构的CPU

8086是16位机,16位结构(与16位机,字长为16位含义相同)表示:

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

2、寄存器的最大宽度为16位

3、寄存器和运算器之间的通路为16位

对于16位CPU,能一次性处理、运输、暂时存储16位的信息,如地址。

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

8086CPU有20位地址总线,可以传送20位地址,但8086CPU又是16位结构,因此其内部用两个16位地址合成一个20位的物理地址。

在这里插入图片描述

具体步骤如下:

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

2、段地址和偏移地址通过内部总线送入地址加法器

3、地址加法器将两个16位地址合成一个20位的物理地址,方法为段地址*16+偏移地址

4、通过内部总线将20位地址送入输入输出控制电路,然后送上地址总线直至内存

2.8 段的概念

内存并没有分段,段的划分来自于CPU,,由于8086CPU用“基础地址(段地址*16)+偏移地址=物理地址”的方法,使得我们可以用分段的方式来管理内存

在这里插入图片描述

对于10000H100FFH的内存单元,既可以看作基础地址(起始地址)为10000H,段地址为1000H,大小为100H的一个段,也可以看作10000H1007FH和10080H~100FFH两个段,基础地址为10000H和10080H,段地址为1000H和1008H,大小都为80H。

可以根据需要,将若干地址连续的内存单元看作一个段,用段地址*16来定位段的起始地址(基础地址),用偏移地址定位段中的内存单元,同时要注意一个段的起始地址必定是16的倍数(20001H显然不会是起始地址),由于偏移地址为16位,因此可以找到2^16个内存单元,所以一个段的长度最大为64KB。

补充:

1、一个内存单元如21F60H,可以由不同的段地址和偏移地址形成

2、一般用数据存在内存2000:1F60单元中或数据存在内存的2000段中的1F60H单元中来表示数据存在内存21F60H单元中。

检测:有一数据存放在内存20000H单元中,现给定段地址SA,则SA应满足条件最小为_1001H_,最大为_2000H_.

解释:最大很简单,最小:因为偏移地址最大为FFFFH,20000H-FFFFH=10001H,因为基础地址必为16的倍数,所以应为10010H,所以段地址最小为1001H。

2.9 段寄存器

段地址在8086CPU的段寄存器中存放,8086CPU有4个段寄存器:CS、DS、SS、ES。

2.10 CS和IP

CS为代码寄存器,IP为指令寄存器,任意时刻,设CS中的内容为M,IP中的内容为N,8086CPU将从内存M*16+N单元开始,读取一条指令并执行,也可以表示为任意时刻CPU将CS:IP指向的内容当作指令执行。

在这里插入图片描述

工作过程如下:

1、从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器

2、IP=IP+所读取指令的长度,从而指向下一条指令

3、执行指令,转到步骤1,重复这个过程(注意是先IP自增,再执行指令)

8086CPU加电启动或复位后,CS和IP被设置为FFFFH和0000H,即从FFFF0H单元中读取指令执行

所以CS和IP的重要性在于它们的内容提供了CPU要执行指令的地址,在内存中,指令和数据没有任何区别都是二进制信息,但CPU将CS:IP指向的内存单元中的内容看作指令,如果说,内存中的一段信息曾被CPU执行过的话,那它所在的内存单元必然被CS:IP指向过。

2.11 修改CS、IP的指令

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

一个最简单的可以修改CS、IP的指令为jmp指令,若想同时改变两个寄存器的值,可以用形如“jmp 段地址:偏移地址”的指令完成,如jmp 2AE3:3,执行后,CS=2AE3H,IP=0003H。

若只修改IP的内容,用形如“jmp 某一合法寄存器”完成,如jmp ax,执行后IP的值为ax的值,CS的值不变。

2.12 代码段

我们可以将长度为N(N<=64KB)的一组代码存在一组地址连续、起始地址为16的倍数的内存单元中,我们可以认为这段内存是用来存放代码的,从而定义了一个代码段

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

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

将一段内存当作代码段,仅仅是人为的一种安排,CPU不会因此就自动得将这个代码段中的信息当作指令来执行,CPU只认CS:IP指向的内存单元中的内容为指令,因此必须将CS:IP指向代码段第一条指令的首地址,若想让上面的代码段得到执行,可设CS=123BH、IP=0000H。

检测:

下面的3条指令执行后,CPU几次修改IP?最终IP中的值是多少?

mov ax,bx
sub ax,ax
jmp ax

内存单元中的内容为指令,因此必须将CS:IP指向代码段第一条指令的首地址,若想让上面的代码段得到执行,可设CS=123BH、IP=0000H。

检测:

下面的3条指令执行后,CPU几次修改IP?最终IP中的值是多少?

mov ax,bx
sub ax,ax
jmp ax

解:4次,分别为三条语句结束后以及第三条语句执行后,这三条语句执行后ax中的值为0000H,所以IP的值为0000H。

发布了84 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43569916/article/details/104132824