汇编语言基础知识摘要(《汇编语言》王爽)第 2 / 17 章
2015-11-28 17:00
232 查看
一个典型的CPU由运算器、控制器、寄存器等器件构成,这些器件靠内部总线相连。第一章中所说的总线,相对于CPU内部来说是外部总线。内部总线实现CPU内部各个器件之间的联系,外部总线实现CPU和主板上其他器件的联系。简单地说,在CPU中:
运算器进行信息处理;
寄存器进行信息存储;
控制器控制各种器件进行工作;
内部总线链接各种器件,在它们之间进行数据的传送。
对于一个汇编程序员来说,CPU中的主要部件是寄存器。寄存器是CPU中程序员可以用指令读写的部件。程序员通过改变各种寄存器中的内容来实现对CPU的控制。
不同的CPU,寄存器的个数、结构是不相同的。8086CPU有14个寄存器,每个寄存器有一个名称。这些寄存器是:AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。
通用寄存器:AX、BX、CX、DX,这4个寄存器通常用来存放一般性的数据。
8086CPU的上一代CPU中的寄存器都是8位的,为了保证兼容性,使原来基于上代CPU编写的程序稍加修改就可以运行在8086之上,8086CPU的AX、BX、CX、DX这4个寄存器都可分为两个可独立使用的8位寄存器来用:
AX可分为AH和AL;
BX可分为BH和BL;
CX可分为CH和CL;
DX可分为DH和DL;
出于对兼容性的考虑,8086CPU可以一次性处理以下两种尺寸的数据:
字节:记为byte,一个字节由8个bit组成,可以存在8位寄存器中。
字:记为word,一个字由两个字节组成,这两个字节分别称为这个字的高位字节和低位字节。
![](http://images2015.cnblogs.com/blog/838221/201511/838221-20151128155519874-1775857844.jpg)
为了区分不同的进制,在十六进制表示的数据的后面加H,在二进制表示的数据的后面加B,十进制表示的数据的后面什么也不加。如:十进制:20000,十六进制:4E20H,二进制:0100111000100000B。
物理地址:所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,我们将这个唯一的地址称为物理地址。
16位结构:16位结构(16位机、字长为16位等常见说法,与16位结构的含义相同)描述了一个CPU具有下面几方面的结构特性:
运算器一次最多可以处理16位的数据;
寄存器的最大宽度为16位;
寄存器和运算器之间的通路为16位。
8086是16位结构的CPU,这也就是说,在8086内部,能够一次性处理、传输、暂时存储的信息的最大长度是16位的。内存单元的地址在送上地址总线之前,必须在CPU中处理、传输、暂时存放,对于16位CPU,能一次性处理、传输、暂时存储16位的地址。
8086CPU相关部件的逻辑结构:
![](http://images2015.cnblogs.com/blog/838221/201511/838221-20151128162330343-1123975800.jpg)
如图2.6所示,当8086CPU要读写内存时:
(1)CPU中的相关部件提供两个16位的地址,一个称为段地址,另一个称为偏移地址;
(2)段地址和偏移地址通过内部总线送入一个称为地址加法器的部件;
(3)地址加法器将两个16位地址合成为一个20位的物理地址;
(4)地址加法器通过内部总线将20位物理地址送入输入输出控制电路;
(5)输入输出控制电路将20位物理地址送上地址总线;
(6)20位物理地址被地址总线传送到存储器。
地址加法器采用物理地址=段地址×16+偏移地址的方法用段地址和偏移地址合成物理地址。
![](http://images2015.cnblogs.com/blog/838221/201511/838221-20151128163156827-1572347939.jpg)
“段地址×16+偏移地址=物理地址”的本质含义是:CPU在访问内存时,用一个基础地址(段地址×16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。
更一般地说,8086CPU的这种寻址功能是“基础地址+偏移地址=物理地址”寻址模式的一种具体实现方案。
内存并没有分段,段的划分来自于CPU,由于8086CPU用“基础地址(段地址×16)+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存。
在编程时可以根据需要,将若干地址连续的内存单元看作一个段,用段地址×16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。有两点需要注意:
段地址×16必然是16的倍数,所以一个段的起始地址也一定是16的倍数;
偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB。
“数据在21F60H内存单元中。”这句话对于8086CPU机一般不这样讲,取而代之的是两种类似的说法:①数据存在内存2000:1F60单元中;②数据存在内存的2000段中的1F60单元中。这两种描述都表示“数据在内存21F60单元中”。
可以根据需要,将地址连续、起始地址为16的倍数的一组内存单元定义为一个段。
8086CPU有4个段寄存器:CS、DS、SS、ES。
8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行。
![](http://images2015.cnblogs.com/blog/838221/201511/838221-20151128171313874-2147249251.jpg)
8086CPU的工作过程可以简要描述如下:
从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器;
IP=IP+所读取指令的长度,从而指向下一条指令;
执行指令。转到步骤1,重复这个过程。
在8086CPU加电启动或复位后(即CPU刚开始工作时)CS和IP被设置为CS=FFFFH,IP=0000H,即在8086PC机刚启动时,CPU从内存FFFF0H单元中读取指令执行,FFFF0H单元中的指令是8086PC机开机后执行的第一条指令。
在内存中,指令和数据没有任何区别,都是二进制信息,CPU在工作的时候把有的信息看作指令,有的信息看作数据。CPU将CS:IP指向的内存单元中的内容看作指令,因为,在任何时候,CPU将CS、IP中的内容当作指令的段地址和偏移地址,用它们合成指令的物理地址,到内存中读取指令码,执行。
如果说,内存中的一段信息曾被CPU执行过的话,那么,它所在的内存单元必然被CS:IP指向过。
能够改变CS、IP的内容的指令被统称为转移指令。
“jmp 段地址:偏移地址”指令的功能为:用指令中给出的段地址修改CS,偏移地址修改IP。
若想仅修改IP的内容,可用形如“jmp 某一合法寄存器”的指令完成,指令的功能为:用寄存器中的值修改IP。
代码段:对于8086PC机,在编程时,可用根据需要,将一组内存单元定义为一个段。我们可以将长度为N(N≤64KB)的一组代码,存在一组地址连续、起始地址为16的倍数的内存单元中,我们可以认为,这段内存是用来存放代码的,从而定义了一个代码段。
如何使得代码段中的指令被执行呢?将一段内存当作代码段,仅仅是我们在编程时的一种安排,CPU并不会由于这种安排,就自动地将我们定义的代码段中的指令当作指令来执行。CPU只认被CS:IP指向的内存单元中的内容为指令。所以,要让CPU执行我们放在代码段中的指令,必须要将CS:IP指向所定义的代码段中的第一条指令的首地址。
Debug程序:Debug是DOS、Windows都提供的实模式(8086方式)程序的调试工具。使用它,可以查看CPU各种寄存器中的内容、内存的情况和在机器码级跟踪程序的运行。
学习汇编过程中,用到的Debug功能(共有20多个,以下是常用的命令):
用Debug的 R 命令查看、改变CPU寄存器的内容;
用Debug的 D 命令查看内存中的内容;
用Debug的 E 命令改写内存中的内容;
用Debug的 U 命令将内存中的机器指令翻译成汇编指令;
用Debug的 T 命令执行一条机器指令;
用Debug的 A 命令以汇编指令的格式在内存中写入一条机器指令。
进入Debug:【开始】-->【运行】-->输入“command”,确定-->进入DOS后,输入debug。
运算器进行信息处理;
寄存器进行信息存储;
控制器控制各种器件进行工作;
内部总线链接各种器件,在它们之间进行数据的传送。
对于一个汇编程序员来说,CPU中的主要部件是寄存器。寄存器是CPU中程序员可以用指令读写的部件。程序员通过改变各种寄存器中的内容来实现对CPU的控制。
不同的CPU,寄存器的个数、结构是不相同的。8086CPU有14个寄存器,每个寄存器有一个名称。这些寄存器是:AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。
通用寄存器:AX、BX、CX、DX,这4个寄存器通常用来存放一般性的数据。
8086CPU的上一代CPU中的寄存器都是8位的,为了保证兼容性,使原来基于上代CPU编写的程序稍加修改就可以运行在8086之上,8086CPU的AX、BX、CX、DX这4个寄存器都可分为两个可独立使用的8位寄存器来用:
AX可分为AH和AL;
BX可分为BH和BL;
CX可分为CH和CL;
DX可分为DH和DL;
出于对兼容性的考虑,8086CPU可以一次性处理以下两种尺寸的数据:
字节:记为byte,一个字节由8个bit组成,可以存在8位寄存器中。
字:记为word,一个字由两个字节组成,这两个字节分别称为这个字的高位字节和低位字节。
![](http://images2015.cnblogs.com/blog/838221/201511/838221-20151128155519874-1775857844.jpg)
为了区分不同的进制,在十六进制表示的数据的后面加H,在二进制表示的数据的后面加B,十进制表示的数据的后面什么也不加。如:十进制:20000,十六进制:4E20H,二进制:0100111000100000B。
物理地址:所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,我们将这个唯一的地址称为物理地址。
16位结构:16位结构(16位机、字长为16位等常见说法,与16位结构的含义相同)描述了一个CPU具有下面几方面的结构特性:
运算器一次最多可以处理16位的数据;
寄存器的最大宽度为16位;
寄存器和运算器之间的通路为16位。
8086是16位结构的CPU,这也就是说,在8086内部,能够一次性处理、传输、暂时存储的信息的最大长度是16位的。内存单元的地址在送上地址总线之前,必须在CPU中处理、传输、暂时存放,对于16位CPU,能一次性处理、传输、暂时存储16位的地址。
8086CPU相关部件的逻辑结构:
![](http://images2015.cnblogs.com/blog/838221/201511/838221-20151128162330343-1123975800.jpg)
如图2.6所示,当8086CPU要读写内存时:
(1)CPU中的相关部件提供两个16位的地址,一个称为段地址,另一个称为偏移地址;
(2)段地址和偏移地址通过内部总线送入一个称为地址加法器的部件;
(3)地址加法器将两个16位地址合成为一个20位的物理地址;
(4)地址加法器通过内部总线将20位物理地址送入输入输出控制电路;
(5)输入输出控制电路将20位物理地址送上地址总线;
(6)20位物理地址被地址总线传送到存储器。
地址加法器采用物理地址=段地址×16+偏移地址的方法用段地址和偏移地址合成物理地址。
![](http://images2015.cnblogs.com/blog/838221/201511/838221-20151128163156827-1572347939.jpg)
“段地址×16+偏移地址=物理地址”的本质含义是:CPU在访问内存时,用一个基础地址(段地址×16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。
更一般地说,8086CPU的这种寻址功能是“基础地址+偏移地址=物理地址”寻址模式的一种具体实现方案。
内存并没有分段,段的划分来自于CPU,由于8086CPU用“基础地址(段地址×16)+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存。
在编程时可以根据需要,将若干地址连续的内存单元看作一个段,用段地址×16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。有两点需要注意:
段地址×16必然是16的倍数,所以一个段的起始地址也一定是16的倍数;
偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB。
“数据在21F60H内存单元中。”这句话对于8086CPU机一般不这样讲,取而代之的是两种类似的说法:①数据存在内存2000:1F60单元中;②数据存在内存的2000段中的1F60单元中。这两种描述都表示“数据在内存21F60单元中”。
可以根据需要,将地址连续、起始地址为16的倍数的一组内存单元定义为一个段。
8086CPU有4个段寄存器:CS、DS、SS、ES。
8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行。
![](http://images2015.cnblogs.com/blog/838221/201511/838221-20151128171313874-2147249251.jpg)
8086CPU的工作过程可以简要描述如下:
从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器;
IP=IP+所读取指令的长度,从而指向下一条指令;
执行指令。转到步骤1,重复这个过程。
在8086CPU加电启动或复位后(即CPU刚开始工作时)CS和IP被设置为CS=FFFFH,IP=0000H,即在8086PC机刚启动时,CPU从内存FFFF0H单元中读取指令执行,FFFF0H单元中的指令是8086PC机开机后执行的第一条指令。
在内存中,指令和数据没有任何区别,都是二进制信息,CPU在工作的时候把有的信息看作指令,有的信息看作数据。CPU将CS:IP指向的内存单元中的内容看作指令,因为,在任何时候,CPU将CS、IP中的内容当作指令的段地址和偏移地址,用它们合成指令的物理地址,到内存中读取指令码,执行。
如果说,内存中的一段信息曾被CPU执行过的话,那么,它所在的内存单元必然被CS:IP指向过。
能够改变CS、IP的内容的指令被统称为转移指令。
“jmp 段地址:偏移地址”指令的功能为:用指令中给出的段地址修改CS,偏移地址修改IP。
若想仅修改IP的内容,可用形如“jmp 某一合法寄存器”的指令完成,指令的功能为:用寄存器中的值修改IP。
代码段:对于8086PC机,在编程时,可用根据需要,将一组内存单元定义为一个段。我们可以将长度为N(N≤64KB)的一组代码,存在一组地址连续、起始地址为16的倍数的内存单元中,我们可以认为,这段内存是用来存放代码的,从而定义了一个代码段。
如何使得代码段中的指令被执行呢?将一段内存当作代码段,仅仅是我们在编程时的一种安排,CPU并不会由于这种安排,就自动地将我们定义的代码段中的指令当作指令来执行。CPU只认被CS:IP指向的内存单元中的内容为指令。所以,要让CPU执行我们放在代码段中的指令,必须要将CS:IP指向所定义的代码段中的第一条指令的首地址。
2.9~2.12 小结 |
(1)段地址在8086CPU的段寄存器中存放。当8086CPU要访问内存时,由段寄存器提供内存单元的段地址。 8086CPU有4个段寄存器,其中CS用来存放指令的段地址。 |
(2)CS存放指令的段地址,IP存放指令的偏移地址。 8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行。 |
(3)8086CPU的工作过程: ① 从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器; ②IP指向下一条指令; ③执行指令。(转到步骤①,重复这个过程。) |
(4)8086CPU提供转移指令修改CS、IP的内容。 |
学习汇编过程中,用到的Debug功能(共有20多个,以下是常用的命令):
用Debug的 R 命令查看、改变CPU寄存器的内容;
用Debug的 D 命令查看内存中的内容;
用Debug的 E 命令改写内存中的内容;
用Debug的 U 命令将内存中的机器指令翻译成汇编指令;
用Debug的 T 命令执行一条机器指令;
用Debug的 A 命令以汇编指令的格式在内存中写入一条机器指令。
进入Debug:【开始】-->【运行】-->输入“command”,确定-->进入DOS后,输入debug。
相关文章推荐
- ubuntu 14.04 下编译QT程序出错误:can't find -lGL error
- cf(413A,B,C)
- DojoGetting Started
- 《我们到底应该怎么吃》读书笔记-- 待续
- 运动的球(1)
- 1-4-08:判断一个数能否同时被3和5整除
- sql clr项目注意
- VUE(现代库) VS jquery(传统库)
- nyoj 138 找球号(二)
- HTML中<form>表单method的get方式和post方式
- HDFS Rolling Upgrade
- 在Legacy BIOS与UEFI 两种模式安装Windows 8操作系统的方法
- 1-4-07:收集瓶盖赢大奖
- 关于浏览器兼容的细节
- HDFS NFS Gateway
- cocoa和cocoa Touch的区别
- Spark中加载本地(或者hdfs)文件以及SparkContext实例的textFile使用
- myeclipse 没有提示时的设置
- PHP如何检测一个UTF-8字符串里有没有繁体字
- android launcher3修改内置的系统图标显示