0x01 寄存器概念
一个典型的CPU由运算器,控制器,寄存器(CPU工作原理)等器件构成,这些器件靠内部总线相连。前一章所说的总线,相对于CPU内部来说是外部总线。内部总线实现CPU内部各个器件之间的联系,外部总线实现CPU和主板上其他器件的联系。
CPU内部构造:
运算器进行信息处理
寄存器进行信息存储
控制器控制各种器件进行工作
-
内部总线连接各种器件,在他们之间进行数据的传送。
对汇编程序员来说,CPU中主要的部件是寄存器,寄存器是CPU中程序员可以用指令读写的部件,程序员通过改变各种寄存器中的内容来实现对CPU的控制
不同的CPU,寄存器的个数,结构是不同构造的。8086的寄存器有14个每个寄存器都有相应的名称
分别是 AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW 后面再介绍
0x02 通用寄存器
8086CPU的所有寄存器都是16位的,可以存放两个字节,AX,BX,CX,DX这四个寄存器统称用来存放一般性的数据,被称为通用寄存器。
一个16为寄存器可以存储一个16位的数据,数据再寄存器中的情况如下图
8086CPU最开始是8为的,为了保证兼容性后代的CPU在AX,BX,CX,DX这四个通用寄存器都可以分为两个可独立使用的8位寄存器来用
- AX可以分为AH和AL
- BX可以分为BH和BL
- CX可以分为CH和CL
- DX可以分为DH和DL
AX的低8位(07)构成了AL寄存器,高8位(815)构成了AH寄存器。
下图展示8位寄存器的数据存储情况
0x03 字在寄存器中的存储
对兼容性考虑,8086CPU可以一次性处理一下两种尺寸的数据
- 字节: 即为byte 一个字节由8个bit组成,可以存放在8位寄存器中
- 字: 即为word 一个字由两个字节组成,这两个字节分别称为这个字的高位字节和地位字节
关于数制的讨论
任何数据,到了计算机中都是以二进制的形式存放的,为了描述不同的问题,有经常将他们用其他的进制表示。比如2.4中的寄存器AX的数据是0100111000100000这是AX种的信息本身,可以用不通用的逻辑意义来看待它是,可以将它看做一个数值,大小是2000,或者十六进制的4E20
由于一个内存单元可以存放8为数据,CPU中的寄存器又可存放N个8位的数据。也就是说,计算机中的数据大多是由1~N个8位数据构成的,很多时候需要看数据是由多少个字节组成的我们可以用十六进制表示例如20000写成4E20就可以直观的看出,这个数据是由4E和20两个8位数据构成的,如果AX中存放得是4E20,则AH是4E,AL这是20,这种表示方法可以很容易直观分析,以后会经常用16进制表示数值
0x04 几条汇编指令
举例
程序段中的执行情况可能出现以下几种
一
(原AX,BX中的值为:0000H)
程序段中的指令 | 指令执行后AX的数据 | 指令执行后BX的数据 |
---|---|---|
MOV AX,8226H | 8662H | 0000H |
MOV BX,8226H | 8662H | 8662H |
ADD AX,BX | 详解2.1 | 8662H |
详解2.1
分析,ADD 相加的记过是1044CH 因AX是为16为寄存器,只能放4位十六进制的数据,所以最高位的1不能再ax中保持,AX的数据为044CH。
二
程序段中的指令 | 执行指令后的AX的数值 | 执行指令后的BX的数值 |
---|---|---|
MOV AX,0026H | 0026H | 0000H |
MOV BX,0026H | 0026H | 0026H |
ADD al,bl | 0040H | 0026H |
ADD ah,bl | 2640H | 0026H |
MOV ah,0 | 0040H | 0026H |
ADD al,85H | 00C5H | 0026H |
ADD al,93H | 详解2.2 | 0026H |
详解 2.2
ADD相加后 al的值为158H 但al为8位寄存器,只能存放两个至六进制的数据,最高为的1丢失,ax中的数据就显示为:0058H (这里丢的丢失,指的是进位值不能再8位寄存器中保存,但是CPU并不真的丢弃这个进位制,后面详解)
0x05 物理地址
CPU访问内存单元时,要给出内存单元的地址。所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间都有唯一地址,我们将这个唯一地址成为物理地址。
CPU通过地址总线送入存储器的,必须是一个内存单元的物理地址。在CPU向地址总线上发出物理地址之前,必须要在内部先形成这个物理地址。
0x06 16位结构的CPU
概括地讲,16位结构(16位机,字长为16位等常见说法,与16位结构的含义相同)描述了一个CPU具有以下几方面的结构特性
- 运算器一次最多可以处理16位数的数据
- 寄存器的最大宽度位16位
- 寄存器和运算器之间的通路位16位
也可以总的来说是CPU上的数据总线宽度位16位
代表机器 8086CPU
0x07 8086CPU给出物理地址的方法
8086CPU有20位地址总线,可以传送20位地址,达到1MB殉职能力。8086CPU又是16位结构,在内部一次处理地址为16位,表示出的寻址能力只有65KB
8086CPU采用一种在内部用两个16位地址合成的方法形成一个20位的物理地址
8086CPU相关部件的逻辑结构如图
由上图所示,当8086CPU要读写内存时:
- CPU中的相关部件提供两个16位地址,一个称为段地址,另一个称为偏移地址
- 段地址和偏移地址通过内部总线送入一个成为地址加法器的部件
- 地址加法器将两个16位地址合成一个20位的物理地址
- 地址加法器通过内部总线将20位物理地址送入输入输出控制电路
- 输入输出控制电路将20位物理地址送上地址总线
- 20位物理地址被地址总线传送到存储器
地址加法器采用的时 物理地址=段地址X16+偏移地址的方法用段地址和偏移地址合成物理地址。
例 8086CPU 访问地址位123C8H的内存单元
段地址X16的讨论
段地址X16还有一种说法时左移4位,这里的左移4位就是二进制左移四位。
例一个数据为 2H,二进制是形式为10B,对其进行左移运算
左移位数 | 二进制 | 十六进制 | 十进制 |
---|---|---|---|
0 | 10B | 2H | 2 |
1 | 100B | 4H | 4 |
2 | 1000B | 8H | 8 |
3 | 10000B | 10H | 16 |
4 | 100000B | 20H | 32 |
也可以从上面看出来
- 左移N位,相当于该数据乘以2的N次方
- 段地址X16=二进制形式左移4位
进一步思考
一个数据的十六进制左移1位相当于乘以16,十进制数据左移一位相当于乘以10
0x08 段地址X16+偏移地址=物理地址 的本质意义
段地址X16+偏移地址=物理地址 的本质含义时:CPU在访问内存是,用一个基础地址(段地址X16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。可以看作 “基础地址+偏移地址=物理地址”
0x08 段的概念
首先,内存并没有分段,段的划分来自于CPU,将若干个连续的地址的内存内存单元看做一个段,用段地址X16
定位段的骑士地址(基础地址),用偏移地址定位段中的内存单元。有两点要注意:
- 段地址X16必须是16的倍数,所以一个段的骑士地址也一定是16的倍数
- 偏移地址为16位,16位地址是寻址能力为64KB,所以一个段的最大长度为64KB
代码段:我们可以根据需要,将一组地址连续,起始地址为16的倍数的内存单元划为一组,将他们都用来存放代码,就是我们所说的代码段
0x09 内存单元地址小结
- CPU访问内存单元时,必须向内存提供内存单元的物理地址,8086CPU在内部用段地址和偏移地址位移相加的方法最终所形成的的物理地址
- CPU可以用不同的段地址和偏移地址形成同一个物理地址
- 如果给定一个段地址,仅通过变化偏移地址来寻址。
0x10 段寄存器
段地址在8086CPU的段寄存器存放。8086CPU有四个寄存器:CS,DS,SS,ES当8086CPU要访问内存由这4个段寄存器提供内存单元的段地址。
0x11 CS和IP
CS和IP是8086CPU中最关键的两个寄存器,他们指示了CPU当前要读取指令的地址。CS为代码段寄存器,IP为指令寄存器。
在8086PC机中,任意时刻,设CS中的内容为M,IP内容为N,8086CPU将从内存Mx6+N单元开始,读取一条指令并执行也可以说8086机中,任意时刻,CPU将CS:IP指向的内容当做指令来执行
例:初始状态(CS:2000h,IP000H,CPU将从内存2000Hx16+0000H处读取指令执行)
上图解释
- 上图是在逻辑结构,宏观过程的层面上进行的,隐蔽了CPU的物理结构,是对新手来说容易理解的一个过程
- 当前 CS中的内容为2000H IP为0000H
- 地址200000H~20002H 内容为 B8 23 01 长度为:3Byte 对应的汇编指令为 mov ax,0123H
- 地址20006~20007H 内容为89 D8 长度为:3Byte 对应的汇编指令为 mov ax,bx
下面一系列图展示了8086CPU读取,执行一条指令的过程
注: 读取一条指令后,IP值自动增加,以使CPU可以读取下一条指令。因目前读入的指令为B82301长度为3个字节,所以IP中的值+3.此时CS:IP指向内存单元2000:0003
下一系列图展示8086继续读取,执行3条指令的过程。注意IP的变化 省略一些简要步骤
所有过程的要点:
- 从CS:IP指向的内存单元读取指令,读取指令进入指令缓冲器
- IP=IP+所取的指令长度,从而指向下一条指令
- 执行指令,重新转到1步骤
CPU如何区分二进制信息的是指令和数据,
CPU将CS:IP指向的内存单元中的内容看作指令,因为在任何时候CPU将CS:IP中的内容当做指令的段地址和偏移地址,用他们来合成指令地址,到内存中读取指令执行。
简单来说:CS:IP指向的内容就是指令,其余就是数据
0x12 简单的修改CS:IP
CS,IP内容不会被轻易改变:能够改变CS,IP内容的指令被统称为转移指令(后面详细介绍)
现在讲一个简单的修改指令Jmp Jmp 段地址:偏移地址
例 jmp 2AE3:3 执行后是 CS=2AE3H IP=0003H
他的功能就是跳到给定的段地址和偏移地址
单独修改IP内容
jmp 某一个合法寄存器
用寄存器里的值修改IP
例
jmp ax, 执行前 ax=1000H cs=2000H ip=1003H
执行后 ax=1000H cs=2000H ip=1000H
0x13 小结
段地址在段寄存器中存放,当CPU要访问内存时,段寄存器提供内存单元的段地址,通用寄存器有四个,CS用来存放指令的段地址
CS寄存器放着段地址,IP存放着偏移地址
-
CPU执行指令的大致过程
- 从CS:IP指向的内存单元读取指令,并把指令放入指令缓冲器
- IP指向下一条指令
- 执行 指令 再转到1步骤
Jmp跳转指令