一个典型的CPU由运算器、控制器、寄存器等器件构成,分工如下:
a) 运算器进行信息处理;
b) 寄存器进行信息存储;
c) 控制器控制各种器件进行工作;
d) 内部总线连接各种器件,在它们之间进行数据的传送。
对于汇编程序员来说,CPU中的主要部件是寄存器,寄存器是CPU中程序员可以用指令读写的部件,程序员通过改变各种寄存器中的内容来实现对CPU的控制。不同CPU,寄存器个数、结构是不同的。8086CPU有14个寄存器,每个寄存器都有一个名称,它们是AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。
1、通用寄存器
8086CPU的所有寄存器都是16位,可以存放两个字节。AX、BX、CX、DX这4个寄存器通常用来存放一般性的数据,被称为通用寄存器。它们都可以分为两个可独立使用的8位寄存器来用:
AX可分为AH和AL
BX可分为BH和BL
CX可分为CH和CL
DX可分为DH和DL
2、mov指令和add指令
在写一条汇编指令或一个寄存器的名称时不区分大小写。如mov ax,18和MOV AX,18的含义相同。
mov ax,18 将常数18送入寄存器AX
mov ah,78 将常数78送入寄存器AH
add ax,8 将寄存器AX中的数值加上8
mov ax,bx 将寄存器BX中的数据送入寄存器AX
add ax,bx 将AX和BX中的数值相加,结果存在AX中
在进行数据传送或运算时,要注意指令的两个操作对象的位数应当是一致的,例如
mov ax,bl
mov bh,ax
mov al,20000
add al,100H
都是错误的指令。
3、CPU访问内存
CPU访问内存单元时,要给出内存单元的地址。所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,我们将这个唯一的地址称为物理地址。
CPU通过地址总线送入存储器的,必须是一个内存单元的物理地址。在CPU向地址总线上发出物理地址之前,必须要在内部先形成这个物理地址。不同的CPU可以有不同的形成物理地址的方式。
8086CPU是16位结构,表明:运算器一次最多可以处理16位的数据,寄存器的最大宽度为16位,寄存器和运算器之间的通路为16位。
8086CPU有20位地址总线,可以传送20位地址,达到1M寻址能力。但是8086是16位结构,内部是用两个16位地址合成的方法来形成一个20位的物理地址。 相关的逻辑结构如下图。
当8086CPU要读写内存时:
1) CPU中的相关部件提供两个16的地址,一个称为段地址,另一个称为偏移地址;
2)段地址和偏移地址通过内部总线送入一个称为地址加法器的部件;
3) 地址加法器将两个16位地址合成为一个20位的物理地址;
4) 地址加法器通过内部总线将20位物理地址送入输入输出控制电路;
5)输入输出控制电路将20位物理地址送上地址总线;
6)20位物理地址被地址总线传送到存储器。
地址加法器采用物理地址=段地址*16+偏移地址的方法合成物理地址。
4、段的概念
我们注意到,“段地址”这个名称中包含着"段"的概念,但是实际上,内存并没有分段,段的划分来自于CPU,由于8086计算物理地址的方式,使得我们可以用分段的方式来管理内存。
以后,在编程的时候可以根据需要,将若干地址连续的内存单元看作一个段。注意一个段的起始地址一定是16的倍数,一个段的长度最大位64KB。
CS为代码段寄存器,IP为指令指针寄存器,在8086CPU机中,任意时刻,设CS中的内容为M,IP中的内容为N,8086CPU将从内存M*16+N单元开始,读取一条指令并执行。也可以说CPU将CS:IP指向的内容当作指令执行。
8086CPU的工作过程可以简要描述如下。
1)从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器;
2)IP=IP+所读取指令的长度,从而指向下一条指令;
3)执行指令。转到步骤1),重复这个过程。
在8086CPU加电启动或复位后(即CPU刚开始工作时)CS和IP被设置为CS=FFFFH,IP=0000H,即在8086PC机刚启动时,CPU从内存FFFF0H单元中读取指令执行,FFFF0H单元中的指令是8086PC机开机后执行的第一条指令。
程序员可以通过修改CS、IP中的内容来控制CPU执行目标指令。能够改变CS、IP的内容的指令被统称为转移指令,例如jmp指令。
“jmp 段地址:偏移地址”指令的功能为:用指令中给出的段地址修改CS,偏移地址修改IP。
"jmp 某一合法寄存器"指令的功能为:用寄存器中的值修改IP。
5、代码段
我们可以将长度为N(N<64KB)的一组代码,存在一组地址连续、起始地址为16的倍数的内存单元中,可以认为这段内存时用来存放代码的,从而定义可一个代码段。
如何使得代码段中的指令被执行呢?将一段内存当作代码段,仅仅是我们在编程时的一种安排,CPU并不会由于这种安排,就自动的将我们定义的代码段中的指令当作指令来执行。所以我们必须将CS:IP指向所定义的代码段中的第一条指令的首地址。