做网站公司价格唐山做网站的电话
《汇编语言》- 读书笔记 - 第2章-寄存器
- 2.0 8086CPU 寄存器
 - 段地址:偏移地址
 
- 2.1 通用寄存器
 - 2.2 字在寄存器中的存储
 - 2.3 几条汇编指令
 - 表2.1汇编指令举例
 - 表2.2 程序段中指令的执行情况之一
 - 问题 2.1
 - 表2.3 程序段中指令的执行情况之二
 - 问题 2.2
 
- 检测点 2.1
 - 2.4 物理地址
 - 2.5 16位结构的CPU
 - 2.6 8086CPU给出物理地址的方法
 - 2.7 “段地址X16+偏移地址=物理地址”的本质含义
 - 2.8 段的概念
 - 内存单元地址小结
 - 检测点 2.2
 - 2.9 段寄存器
 - 2.10 CS和IP
 - 2.11 修改 CS、IP 的指令
 - 问题 2.3
 
- 2.12 代码段
 - 2.9~2.12 小结
 - 检测点 2.3
 
CPU由运算器、控制器、寄存器等构成,内部总线连接这些器件,外部总线连接主板上其他器件。
 对于汇编程序员来说,寄存器是最主要的部件,我们能做的就是通过改变寄存器中的内容来控制CPU。
 不同CPU的寄存器个数和结构不同。8086CPU有14个寄存器,包括:
 通用寄存器:AX、BX、CX、DX
 段寄存器:CS、SS、DS、ES
 偏移指针寄存器:SI、DI、SP、BP、IP
 标志寄存器:PSW
2.0 8086CPU 寄存器
段地址:偏移地址
| 段地址:偏移地址 | 说明 | 
|---|---|
| CS:IP | 指向下一条指令的物理地址 | 
| SS:SP | 指向当前堆栈顶部的物理地址 | 
| DS:BX | 指向数据的物理地址 | 
| DS:SI | 指向数据的物理地址。例:复制中的源 | 
| DS:DI | 指向数据的物理地址。例:复制中的目标 | 
2.1 通用寄存器
8086CPU 的所有寄存器都是 16 位的,可以存放两个字节。
 AX、BX、CX、DX这4个寄存器通常用来存放一般性的数据,被称为通用寄存器。
- 数据在寄存器中的存储情况
 

- 四个通用寄存器都可以拆分为高低位,分开使用。
 

2.2 字在寄存器中的存储
8bit(位)组成一个Byte(字节)。2字节组成一个字 。
 所以一个字包含高和低两个字节。共16位。

 我们再看个例子:9527H这个字的数据可以当作整体来用,表示:
 9527H = 10010101 00100111 =38183
 也可以把高低位拆开分别使用,表示:
 高位:95H = 10010101B = 149
 低位:27H = 00100111B = 39
| 进制 | 寄存器值 | 高位 | 低位 | 
|---|---|---|---|
| 16 | 9527H | 95 | 27 | 
| 2 | 1001010100100111B | 10010101 | 00100111 | 
| 10 | 38183 | 149 | 39 | 
补充:10进制数直接与高低位对应很难理解。需要转为2或16进制分出高低位再转成10进制。
2.3 几条汇编指令
- 写
汇编指令或寄存器名时,不区分大小写。 - 下面的两个"问题"主要是介绍了寄存器执行加法后
溢出的问题。 
表2.1汇编指令举例
| 汇编指令 | 控制CPU完成的操作 | 用高级语言的语法描述 | 
|---|---|---|
| mov ax,18 | 将18 送入寄存器AX | AX=18 | 
| mov ah,78 | 将78送入寄存器AH | AH-78 | 
| add ax,8 | 将寄存器AX中的数值加上8 | AX=AX+8 | 
| mov ax,bx | 将寄存器BX中的数据送入寄存器AX | AX-BX | 
| add ax,bx | 将AX和BX中的数值相加,结果存在AX中 | AX=AX+BX | 
表2.2 程序段中指令的执行情况之一
(原 AX 中的值:0000H,原 BX 中的值:0000H)
| 程序段中的指令 | 指令执行后AX中的数据 | 指令执行后BX中的数据 | 
|---|---|---|
| mov ax,4E20H | 4E20H | 0000H | 
| add ax,1406H | 6226H | 0000H | 
| mov bx,2000H | 6226H | 2000H | 
| add ax,bx | 8226H | 2000H | 
| mov bx,ax | 8226H | 8226H | 
| add ax,bx | ?(参见问题2.1) | 8226H | 
问题 2.1
- 指令执行后AX中的数据为多少?
 
8226H + 8226H = 1044CH
 但 AX 只有16位(对应4个16进制数)
 所以溢出了,最高位的1丢失。
 最后AX中剩下的就只有044CH
表2.3 程序段中指令的执行情况之二
| 程序段中的指令 | 指令执行后AX中的数据 | 指令执行后BX中的数据 | 
|---|---|---|
| mov ax,001AH | 001AH | 0000H | 
| mov bx,0026H | 001AH | 0026H | 
| add al,bl | 0040H | 0026H | 
| add ah,bl | 2640H | 0026H | 
| add bh,al | 2640H | 4026H | 
| mov ah,0 | 0040H | 4026H | 
| add al,85H | 00C5H | 4026H | 
| add al,93H | ?(参见问题2.2) | 4026H | 
问题 2.2
指令执行后AX中的数据为多少?
C5H + 93H = 158H
 但 AL 只有8位(对应2个16进制数)
 所以溢出了,最高位的1丢失。
 最后AL中剩下的就只有58H
 注意:add al,93H进行的是 8 位运算。单独使用AL时,它作为一个独立的8位寄存器,和AH无关。并不会把溢出的1放到 AH中去。
在进行数据传送或运算时,要注意指令的两个操作对象的位数应当是一致的,例如:
- 正确的写法
 
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.1
《汇编语言》- 读书笔记 - 检测点 2.1
2.4 物理地址
CPU 访问内存单元时,需要使用物理地址。
 所有的内存单元构成一个线性空间,每个内存单元在其中有唯一的地址,这就是所谓的物理地址。
 不同的 CPU 可以采用不同的方式来形成物理地址。对于 8086CPU,在发送物理地址到地址总线之前,它需要先在内部生成物理地址。
2.5 16位结构的CPU
- 运算器一次最多可以处理 16 位的数据;
 - 寄存器的最大宽度为 16位;
 - 寄存器和运算器之间的通路为 16 位。
 
8086CPU是16位结构,一次性能够处理、传输、暂存信息长度最大为16位。(内存单元的地址也是信息)
2.6 8086CPU给出物理地址的方法
8086CPU有20位地址总线,达到1MB寻址能力。
 也就是说地址总线一次能收发20辆车。
 但CPU一单只能打包16车货。
 如果CPU来一单,就发车。那地址总线上就要跑4辆空车。
 为了不浪费。
 CPU决定一次发两单,每单都少装点货,拼到一起刚好20车,至于谁多谁少,程序员可以根据自己调配。
 一单是段地址,一单是偏移地址。
 在CPU中有一个地址加法器,它用来计算最终的物理地址:
 物理地址 = 段地址x 16 + 偏移地址。
 
- 如图 2.6所示,当8086CPU 要读写内存时:
 
- CPU中的相关部件提供两个16 位的地址,一个称为段地址,另一个称为偏移地址;
 - 段地址和偏移地址通过内部总线送入一个称为地址加法器的部件;
 - 地址加法器将两个 16 位地址合成为一个 20 位的物理地址;
 - 地址加法器通过内部总线将 20 位物理地址送入输入输出控制电路;
 - 输入输出控制电路将 20 位物理地址送上地址总线;
 - 20 位物理地址被地址总线传送到存储器。
 

 
2.7 “段地址X16+偏移地址=物理地址”的本质含义
段地址x16+偏移地址=物理地址的本质含义是:CPU 在访问内存时,用一个基础地址(段地址X16)和一个相对于基础地址的偏移地址相加,得出内存单元的物理地址。
 是 基础地址+偏移地址=物理地址这种寻址模式的一种实现方案。
 例1:
 
 这里如果应用 基础地址+偏移地址=物理地址的寻址模式。2000可视作基址,826可视作偏移地址。
2.8 段的概念
内存中没有段的概念。是8086CPU使用 基础地址+偏移地址=物理地址方式寻址,来分段管理内存。
 
段地址是x16得来的。段起始地址一定是16的倍数。- 偏移地址有16位,范围
0000h~FFFFh。所以一个段最大为64KB。 - 可以根据需要,将地址连续、起始地址为16的倍数的一组内存单元定义为一个段。
 
内存单元地址小结
- CPU可以用不同的
段地址和偏移地址组成同一个物理地址,也就是说同一个物理地址可以有很多种组合方式获得。 - 数据在
21F60H内存单元中。对于8086PC机一般表达为:
2.1. 数据存在内存2000:1F60单元中;
2.2. 数据存在内存的2000H段中的1F60H单元中。 
检测点 2.2
《汇编语言》- 读书笔记 - 检测点 2.2
2.9 段寄存器
8086CPU 有4 个段存器:CS、DS、SS、ES。用来存放内存单元的段地址。
 见:8086CPU 寄存器
2.10 CS和IP
CS:代码段寄存器。存放当前执行指令的代码段的基地址。
 IP:指令指针寄存器。保存着将要执行的指令在段中的偏移量。
 CS:IP:指向接下来要执行的指令的物理地址。
在8086CPU加电启动或复位后(即CPU刚开始工作时)CS和IP被设置为CS=FFFFH,P=0000H,
 即在 8086PC 机刚启动时,CPU 从内存 FFFFOH 单元中读取指令执行,
 FFFFOH单元中的指令是8086PC机开机后执行的第一条指令。
8086机中,任意时刻,CPU将 CS:IP 指向的内容当作指令执行。.
 执行过的一段信息对应的内存单元必然被 CS:IP 指向过。
图 2.10 展示了 8086CPU 读取、执行指的工作原理(图中只包括了和所要说明的问题密切相关的部件,图中数字都为十六进制)。
 
 图2.10说明如下。
- 8086CPU当前状态:
CS中的内容为2000H,IP中的内容为0000H; - 内存
20000H~20009H单元存放着可执行的机器码; - 内存
20000H~20009H单元中存放的机器码对应的汇编指令如下。 
| 地址 | 内容 | 长度 | 对应汇编指令 | 
|---|---|---|---|
20000H~20002H | B8 23 01 | 3Byte | mov ax,0123H | 
20003H~20005H | BB 03 00 | 3Byte | mov bx, 0003H | 
20006H~20007H | 89 D8 | 2Byte | mov ax,bx | 
20008H~20009H | 01 D8 | 2Byte | add ax,bx | 
下面的一组图(图2.11~图 2.19),以图 2.10 描述的情况为初始状态,展示了8086CPU读取、执行一条指令的过程。注意每幅图中发生的变化(下面对 8086CPU 的描述,是在逻辑结构、宏观过程的层面上进行的,目的是使读者对 CPU 工作原理有一个清晰、直观的认识,为汇编语言的学习打下基础。其中隐蔽了 CPU 的物理结构以及具体的工作细节)。

总结 8086CPU的工作过程可以简要描述如下:
- 首先:
CS和IP送入地址加法器,得到CS:IP。
例:CS= 2000h,IP= 0000h 
CS:IP =     CS * 16 + IP
CS:IP =  2000h * 16 + 0000h  ;16进制数 *16 等于左移1位。(进位了嘛)
CS:IP = 20000h      + 0000h
CS:IP = 20000h
 
 
- 到 
20003H~20005H获取mov bx, 0003H执行, IP=IP+3 - 到 
20006H~20007H获取mov ax,bx执行, IP=IP+2 - 到 
20008H~20009H获取add ax,bx执行, IP=IP+2 
2.11 修改 CS、IP 的指令
在 CPU 中,程序员能够用指令读写的部件只有寄存器,通过改变寄存器中的内容实现对 CPU 的控制。程序员改变CS、IP 就实现了控制 CPU执行目标指令。
mov 不能修改 CS、IP 它有专用的指令如:jmp
| 指令 | 说明 | 
|---|---|
jmp 2AE3:3 | 用给定的地址修改CS,IP执行后: CS=2AE3H,IP=0003H。 | 
jmp ax | 用寄存器ax中的值修改IP执行前: ax=1000H,CS=2000H,IP=0003H执行后: ax=1000H,CS=2000H,IP=1000H | 
CPU将从修改后的地址读取指令。
问题 2.3
内存中存放的机器码和对应的汇编指令情况如图 2.27 所示,设 CPU 初始状态:CS=2000H,IP=0000H,请写出指令执行序列。思考后看分析。
 
 分析:
| 执行步骤 | 内存地址 CS:IP  | 机器码 | 汇编指令 | IP指向下一条 | 指令执行后 寄存器变化  | 
|---|---|---|---|---|---|
| 1 | 2000:0000 | B8 22 66 | mov ax, 6622h | IP=IP+3 | AX = 6622h | 
| 2 | 2000:0003 | EA 03 00 00 10 | jmp 1000:3 | IP=IP+5 | CS = 1000h IP = 0003h  | 
| 3 | 1000:0003 | B8 00 00 | mov ax, 0000 | IP=IP+3 | AX = 0000h | 
| 4 | 1000:0006 | 8B D8 | mov bx, ax | IP=IP+2 | BX = 0000h | 
| 5 | 1000:0008 | FF E3 | jmp bx | IP=IP+2 | IP = 0000h | 
| 6 | 1000:0000 | B8 23 01 | mov ax, 0123h | IP=IP+3 | AX = 0123h | 
2.12 代码段
在2.8 段的概念中我们知道了什么是段。
 那么这段内存中如果存放的是指令,我们认为代是个代码段。
 但它本质还只是内存中的一堆01,当CS:IP指向它,CPU就会把它当指令来执行。
 例:
mov ax, 0000	(B8 00 00)
add ax, 0123H	(05 23 01)
mov bx, ax		(8B D8)
jmp bx			(FF E3)
 
这段长度为 10个字节的指令,存放在 123B0H~123B9H 的一组内存单元中。
 假如(使用 jmp)将CS:IP设置为123B:0000 (指向了代码段中的第一条指令的首地址)。CPU就会执行它了。
2.9~2.12 小结
- 段地址在8086CPU的段寄存器中存放。当8086PU要访问内存时,由段寄存器提供内存单元的段地址。8086CPU有4个段寄存器,其中CS用来存放指令的段地址
 - CS存放指令的段地址,IP存放指的偏移地址。8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行
 - 8086CPU的工作过程: 
- 从
CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器 IP指向下一条指令;- 执行指令。(转到步骤1,重复这个过程。)
 
 - 从
 - 8086CPU提供转移指令修改CS、IP的内容。
 
检测点 2.3
《汇编语言》- 读书笔记 - 检测点 2.3

