2 寄存器
- 一个典型的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 -
8086CPU的上一代CPU中寄存器都是8位的,为了保证兼容,8086的AX、BX、CX、DX都可以分为两个可独立使用的8位寄存器来使用
- AX可分为AH和AL
- BX可分为BH和BL
- CX可分为CH和CL
- DX可分为DH和DL
- AX的低8位(0~7位)构成了AL寄存器,高8位构成了AH寄存器,AH和AL寄存器是可以独立使用的8位寄存器
2.2 字在寄存器中的存储
- 8086CPU可以一次性处理以下两种尺寸的数据:
- 字节:记为byte,一个字节由8个bit组成
- 字:记为word,一个字由两个字节组成,这两个字节分别称为这个字的高位字节和低位字节
2.3 几条汇编指令
汇编指令 | 用高级语言的语法描述 |
---|
mov ax,18 | AX = 18 | mov ah,12 | AH = 12 | add ax 8 | AX = AX + 8 | mov ax,bx | AX = BX | add ax,bx | AX = AX + BX |
- 进行运算时,运算结果多出位数的部分会舍弃掉
- 如果运算基于字节基础上,则运算结果多出8位的二进制会舍弃
- 如果运算基于字的基础上,则运算结果多出16位的二进制会舍弃掉
2.4 物理地址
- 所有的内存单元构成的存储空间时一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,也就是物理地址
- 在CPU向地址总线上发出物理地址之前,必须要在内部先形成这个物理地址,不同的CPU可以有不同的形成物理地址的方式。
2.5 16位结构的CPU
- 16位的CPU具有下面几方面的结构特性:
- 运算器一次最多可以处理16位的数据
- 寄存器的最大宽度为16位
- 寄存器和运算器之间的通路为16位
2.6 8086CPU给出物理地址的方法
-
8086CPU有20位地址总线,可以传输20位地址,达到1MB的寻址能力。但其又是16位结构,在内部一次性处理、传输、暂时存储的地址为16位,如果将地址从内部简单地发出,那么它只能送出16位地地址 -
8086CPU采用一种在内部用两个16位地址合成的方法形成一个20位的物理地址 -
地址加法器采用物理地址 = 端地址×16 + 偏移地址的方法用段地址和偏移地址合成物理地址
2.7 “段地址×16+偏移地址=物理地址”的本质含义
- 本质含义:CPU在访问内存时,用一个基础地址(段地址×16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址
- 更一般说,8086CPU这种寻址功能是:基础地址 + 偏移地址 = 物理地址
2.8 段的概念
- 实质上,内存并没有分段,段的划分来自CPU,由于8086CPU用“基础地址+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存
- 在编程时可以根据需要,将若干个地址连续的内存看作是一个段,用段地址×16定位段的起始地址,用偏移地址定义段中的内存单元
- 由于段地址×16必然是16的倍数,所以一个段的起始地址也一定是16的倍数
- 偏移地址为16位,16地址的寻址能力为64KB,所以一个段最大为64KB
- CPU可以用不同的段地址和偏移地址形成同一个物理地址,例如物理地址为21F60H,其段地址和偏移地址可以是2000H和1F60H,段地址和偏移地址也可以是2100H和0F60H等等
2.9 段寄存器
8086CPU有4个段寄存器:CS、DS、SS、ES,当8086CPU要访问内存时由这4个段寄存器提供内存单元的段地址
2.10 CS和IP
- CS和IP是8086CPU中两个最关键的寄存器,它们指示了CPU当前要读取指令的地址。CS为代码段寄存器,IP为指令指针寄存器
- 在8086PC机中,任意时刻,设CS中的内容为M,IP中的内容为N,8086CPU将从M×16+N单元开始,读取一条指令并执行
- 也就是8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行
- 由上述的图可以得知,8086CPU的工作过程可以描述为:
-
- 从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器
-
- IP=IP+所读指令的长度,从而指向下一条指令
-
- 执行指令。转到步骤1,重复这个过程
- 在8086CPU加电启动或复位后(即CPU刚开始工作时)CS和IP被设置为CS=FFFFH,IP=0000H,即在8086机刚启动时,CPU从内存FFFFF0H单元中读取指令执行,FFFF0H单元中的指令是8086PC机开机后执行的第一条指令
2.11 修改CS、IP的指令
- 在CPU中,程序员能够用指令读写的部件只有寄存器,程序员可以通过改变寄存器中的内容实现对CPU的控制
- 8086CPU大部分寄存器的值,都可以用mov指令来改变,mov指令被称为传送指令
- mov指令不能用于设置CS、IP的值,可以通过jmp指令来修改CS、IP的值:
- 同时修改CS、IP的内容:jmp 段地址:偏移地址
- 也就是用指令中给出的段地址修改CS,偏移地址修改IP
- jmp 2AE3:3,执行后,CS=2AE3H,IP=0003H,CPU将从2AE33H处读取指令
- 若想仅修改IP的内容,可以用:jmp 某一合法寄存器
- jmp ax,指令执行前:ax=1000H,CS=2000H,IP=0003H。指令执行后:ax=1000H,CS=2000H,IP=1000H,实质上就是用ax中的值来修改IP中的值
2.12 代码段
- 编程时,我们可以根据需要,将一组内存单元定义为一个段,但是将一段内存当作代码段,仅仅是我们在编程时的一种安排,CPU并不会由于这种安排就自动地将我们定义地代码段中地指令当作指令来执行
实验1 查看CPU和内存,用期绩指令和汇编指令编程
1. Debug的使用
win10不能直接使用debug,所以要下载一些相应的插件,如果为了更方便使用,可以下载win7的虚拟机,可以直接使用debug功能
1.1用R命令查看改变CPU寄存器的内容
-
用R命令来修改寄存器中的内容 -
用R命令修改CS和IP中的内容
1.2 用Debug的D命令查看内存中的内容
-
用D命令查看内存中的内容 -
查看1000:9处的内容 -
列出Debug预设的地址处的内容
- 在使用“d 段地址:偏移地址”之后,接着使用D命令,可列出后续的内容
- 也可以指定D命令查看范围,此时采用“d 段地址:起始偏移地址 结尾偏移地址”
1.3 用Debug的E命令改写内存中的内容
1.4 用E命令向内存中写入机器码,用U命令查看内存中机器起码的含义,用T命令执行内存中的机器码
1.5 用Debug的A命令以汇编指令的形式在内存中写入机器指令
|