汇编语言寄存器相关知识(AX/BX/CX/DX+mov/add+物理地址+段+CS/IP+jmp)
一个典型的CPU由运算器、控制器、寄存器等器件构成,这些器件靠内部总线相连。内部总线实现CPU内部各个器件之间的联系,外部总线实现CPU和主板上其他器件的联系。简单地说,在CPU中:
- 运算器进行信息处理
- 寄存器进行信息存储
- 控制器控制各种器件进行工作
- 内部总线连接各种器件,在它们之间进行数据的传送
对于汇编程序员来说,CPU的主要部件是寄存器。寄存器是CPU中程序员可以用指令读写的部件。程序员通过改变各种寄存器中的内容来实现对CPU的控制。
一、通用寄存器
8086CPU的所有寄存器都是16位的,可以存放两个字节。AX、BX、CX、DX这4个寄存器通常用来存放一般性的数据,被称为通用寄存器。
以AX为例,寄存器的逻辑结构如图2.1所示
一个16位寄存器可以存储一个16位的数据,数据在寄存器中的存放情况如图2.2所示。
8086CPU的上一代CPU中的寄存器都是8位的,为了保证兼容,使原来基于上代CPU编写的程序稍加修改就可以运行在8086之上,8086CPU的AX、BX、CX、DX这4个寄存器都可分为两个可独立使用的8位寄存器来用:
- AX可分为AH和AL
- BX可分为BH和BL
- CX可分为CH和CL
- DX可分为DH和DL
以AX为例,8086CPU的16位寄存器分为两个8位寄存器的情况如图2.3所示:
AX的低8位(0~7)构成了AL寄存器,高8位(8~15)构成了AH寄存器。AH和AL寄存器是可以独立使用的8位寄存器。下图展示了16位寄存器及它所分成的两个8位寄存器的数据存储的情况
二、字在寄存器中的存储
8086CPU可以一次性处理以下两种尺寸的数据:
- 字节:记为byte,一个字节由8个bit组成,可以存在8位寄存器中。
- 字:记为word,一个字由两个字节组成,这两个字节分别称为这个字的高位字节和低位字节,如图2.5所示
一个字可以存在一个16位寄存器中,这个字的高位字节和低位字节自然就存在这个寄存器的高8位寄存器和低8位寄存器中。如图2.4所示,一个字型数据20000,存在AX寄存器中,在AH中存储了它的高8位,在AL中存储了它的低8位。AH和AL中的数据,既可以看成是一个字型数据的高8位和低8位,这个字型数据的大小是20000;又可以看成是两个独立的字节型数据,它们的大小分别是78和32.
在后面的表述中,为了区分不同的进制,在16进制的数据后面加H,在二进制表示的数据后面加B,十进制表示的数据后面什么都不加。
三、mov+add汇编指令
我们是通过汇编指令控制CPU进行操作的,首先看下表2.1中的几条指令:
在进行数据传送或运算时,要注意指令的两个操作对象的位数应当是一致的,例如:
mov ax,bx
mov bx,cx
mov ax,18H
mov al,18H
add ax,bx
add ax,20000
等都是正确的指令,而:
mov ax,bl
mov bh,ax
mov al,20000 (8位寄存器最大可存放值为255的数据)
add,al,100H (将一个高于8位的数据加到一个8位寄存器中)
等都是错误的指令,错误的原因都是指令的两个操作对象的位数不一致。
四、物理地址
CPU访问内存单元时,要给出内存单元的地址。所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,我们将这个唯一的地址称为物理地址。
CPU通过地址总线送入寄存器的,必须是一个内存单元的物理地址。在CPU向地址总线上发出物理地址之前,必须要在内部先形成这个物理地址。不同的CPU可以由不同的形成物理地址的方式,接下来讨论8086CPU如何在内部形成内存单元的物理地址。
4.1 16位结构的CPU
概括地讲,16位结构(16位机、字长为16位等常见说法,与16位结构的含义相同)描述了一个CPU具有下面几方面的结构特性:
- 运算器一次最多可以处理16位的数据
- 寄存器的最大宽度为16位
- 寄存器和运算器之间的通路为16位
8086CPU是16位结构的CPU,这也就是说,在8086内部,能够一次性处理、传输、暂时存储的信息的最大长度是16位的。内存单元的地址在送上地址总线之前,必须在CPU中处理、传输、暂时存放,对于16位CPU,能一次性处理、传输、暂时存储16位的地址。
4.2 8086CPU给出物理地址的方法
8086CPU有20位地址总线,可以传送20位地址,达到1MB寻址能力。8086CPU又是16位架构,在内部一次性处理、传输、暂时存储的地址为16位。从8086CPU的内部结构来看,如果将地址从内部简单地发出,那么它只能送出16位的地址,表现出的寻址能力只有64KB。8086CPU实现20位寻址方式的方法是采用一种在内部用两个16位地址合成的方法来形成一个20位的物理地址。
8086CPU相关部件的逻辑结构如图2.6所示:
如上图所示,当8086CPU要读写内存时:
- CPU中的相关部件提供两个16位的地址,一个称为段地址,另一个称为偏移地址
- 段地址和偏移地址通过内部总线送入一个称为地址加法器的部件
- 地址加法器将两个16位地址合成为一个20位的物理地址
- 地址加法器通过内部总线将20位物理地址送入输入输出控制电路
- 输入输出控制电路将20位物理地址送上地址总线
- 20位物理地址被地址总线传送到存储器
地址加法器采用物理地址=段地址×16\times16×16+偏移地址的方法用段地址和偏移地址合成物理地址。例如,8086CPU要访问地址为123C8H的内存单元,此时,地址加法器的工作过程如图2.7所示:
五、段的概念
要注意内存是没有被划分成一个一个的段的,段的划分来自于CPU,由于8086CPU用“基础地址(段地址*16)+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存。如下图所示,我们可以认为:地址10000H-100FFH的内存单元组成一个段,该段的起始地址(基础地址)为10000H,段地址为1000H,大小为100H;我们也可以认为地址10000H-1007FH、10080H-100FFH的内存单元组成两个段,它们的起始地址(基础地址)为:10000H和10080H,段地址为:1000H和1008H,大小都为80H。
在编程时可以根据需要,将若干地址连续的内存单元看作一个段,用段地址×16\times16×16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。有两点需要注意:
- 段地址×16\times16×16必然是16的倍数,所以一个段的起始地址也一定是16的倍数
- 偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB。
练习
1.
观察下面地址,你有什么发现?
物理地址 | 段地址 | 偏移地址 |
---|---|---|
21F60H | 2000H | 1F60H |
2100H | 0F60H | |
21F0H | 0060H | |
21F6H | 0000H | |
1F00H | 2F60H |
结论:CPU可以用不同的段地址和偏移地址形成同一个物理地址。
2.
如果给定一个段地址,仅通过变化偏移地址来进行寻址,最多可定位多少个内存单元?
结论:偏移地址16位,变化范围为0-FFFFH,仅用偏移地址来寻址最多可寻64KB个内存单元。
比如给定段地址1000H,用偏移地址寻址,CPU的寻址范围为:10000H-1FFFFH。
六、段
8086CPU在访问内存时候要由相关部件提供内存单元的段地址和偏移地址,送入加法器合成物理地址。段地址在8086CPU的段寄存器中存放。8086CPU有4个段寄存器:CS、DS、SS、ES。当8086CPU要访问内存时由这4个段寄存器提供内存单元的段地址。接下来看下CS寄存器。
6.1 CS和IP
CS和IP是8086CPU中两个最关键的寄存器,它们指示了CPU当前要读取指令的地址。CS为代码段寄存器,IP为指令指针寄存器,在8086PC机中,任意时刻,设CS中的内容为M,IP中的内容为N,8086CPU将从内存M×16\times16×16+N单元开始,读取一条指令并执行。
也可以这样表述:8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行。
下图展示了8086CPU读取、执行指令的工作原理(图中只包括了和所要说明的问题密切相关的部件,图中数字都为16进制)。
上图说明如下:
- 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的物理结构以及具体的工作细节)。
通过上面的过程展示,8086CPU的工作过程可以简要描述如下:
- 从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器
- IP=IP+所读取指令的长度,从而指向下一条指令
- 执行指令,转到步骤1,重复这个过程
在8086CPU加电启动或复位后(即CPU刚开始工作时)CS和IP被设置为CS=FFFFH,IP=0000H,即在8086PC机刚启动时,CPU从内存FFFF0H单元中读取指令执行,FFFF0单元中的指令是8086PC机开机后执行的第一条指令。
在内存中,指令和数据没有任何区别,都是二进制信息,CPU在工作的时候把有的信息看作指令,有的信息看作数据。CPU识别指令就是根据CS和IP寄存器的值,在任何时候,CPU都使用CS和IP合成指令的物理地址,到内存中读取指令码执行。如果说,内存中的一段信息曾被CPU执行过的话,那么,它所在的内存单元必然被CS:IP指向过。
6.2 修改CS、IP的指令
在CPU中,程序员能够用指令读写的部件只有寄存器,程序员可以通过改变寄存器中的内容实现对CPU的控制。CPU从何处执行指令是由CS、IP中的内容决定的,程序员可以通过改变CS、IP中的内容来控制CPU执行目标指令。
但是注意mov指令不能用于设置CS、IP的值,在8086CPU没有提供这样的功能。8086CPU为CS、IP提供了另外的指令来改变它们的值。能够改变CS、IP的内容的指令被统称为转移指令。接下来介绍下最简单的可以修改CS、IP的指令:jmp指令。
若想同时修改CS、IP的内容,可用形如“jmp 段地址:偏移地址”的指令完成,如:
jmp 2AE3:3,执行后:CS=2AE3H,IP=0003H,CPU将从2AE33H处读取指令。
jmp 3:0B16,执行后:CS=0003H,IP=0B16H,CPU将从00B46H处读取指令。
“jmp 段地址:偏移地址”指令的功能为:用指令中给出的段地址修改CS,偏移地址修改IP。
若想仅修改IP的内容,可用形如“jmp 某一合法寄存器”的指令完成,如:
jmp ax,指令执行前:ax=1000H,CS=2000H,IP=0003H
指令执行后:ax=1000H,CS=2000H,IP=1000H
“jmp 某一合法寄存器”指令的功能为:用寄存器中的值修改IP。
jmp ax,在含义上好似:mov IP,ax。(但是注意并不存在这样的语法)
6.3 代码段
我们可以将长度为N(N<=64KB)的一组代码,存在一组地址连续、起始地址为16的倍数的内存单元中,我们可以认为,这段内存是用来存放代码的,从而定义了一个代码段,比如,将:
mov ax,0000 (B8 00 00)
add ax,0123H (05 23 01)
mov bx,ax (8B D8)
jmp bx (FF E3)
这段长度为10个字节的指令,存放在123B0H~123B9H的一组内存单元中,我们就可以认为,123B0H~123B9H这段内存就是用来存放代码的,是一个代码段,它的段地址为123BH,长度为10个字节。
将一段内存当作代码段,仅仅是我们在编程时的一种安排,CPU并不会由于这种安排,就自动地将我们定义的代码段中的指令当作指令来执行。要让CPU执行我们放在代码段中的指令,必须要将CS:IP指向所定义的代码段中的第一条指令的首地址。对于上面的例子,我们将一段代码存放在123B0H~123B9H内存单元中,将其定义为代码段,如果要让这段代码得到执行,可设CS=123BH、IP=0000H。
练习题
1.
下面的3条指令执行后,CPU几次修改IP?都是在什么时候?最后IP中的值是多少?
mov ax,bx
sub ax,ax
jmp ax
修改四次:
- 第一次在CPU读取"mov ax,bx"后
- 第二次在CPU读取"sub ax,ax"后
- 第三次在CPU读取"jmp ax"后
- 第四次在CPU执行完"mov ax,bx"后
最后IP中的值为0。
汇编语言寄存器相关知识(AX/BX/CX/DX+mov/add+物理地址+段+CS/IP+jmp)相关推荐
- 汇编语言AX,BX,CX,DX寄存器
AX,BX,CX,DX寄存器 这四个寄存器用来存放数据,也就是数据寄存器 AX的大小为2B=16bit(所有也叫16位寄存器) 数据范围:0000 0000 0000 0000----1111 111 ...
- 汇编(8086cpu): AX,BX,CX,DX寄存器
AX,BX,CX,DX寄存器这四个寄存器也被称为通用寄存器.一般用来存放数据,一个寄存器可以存放16bit,也就是2bytes. 所以也被称为16位寄存器. 什么特殊的地方导致这四个寄存器和其他寄存器 ...
- Win-MASM64汇编语言-通用寄存器AX/BX/CX/DX/SI/DI/BP
(1)AX: ①用于数据中转:高级语言反汇编中CPU通常使用ax进行中转数据,比如要往ds寄存器中放数据的话,不可以mov ds,0001H这样写,而是应该先mov ax,0001H,然后再mov d ...
- 汇编中的通用基础寄存器ax,bx,cx,dx等的含意及作用解释
对一些汇编语言中基础的寄存器的代表的字符及含意(基础的) 一.段寄存器 在程序中起到声明段的作用,一般与assume同时出现 1.DS 数据段寄存器 2.ES 附加数据段寄存器 3.CS 代码段寄存器 ...
- [从零学习汇编语言] -寄存器详解
文章目录 前言 一. 存储器与通用寄存器 1. 存储器 2. 寄存器 2.1 通用寄存器 2.2 字在寄存器中的存储 二.地址寄存器 1. 物理地址 1.1 地址寄存器 1.2 8086CPU给出物理 ...
- 汇编语言寄存器说明eax, ebx, ecx, edx, esi, edi, ebp, esp,eip
eax, ebx, ecx, edx, esi, edi, ebp, esp等都是X86 汇编语言中CPU上的通用寄存器的名称,是32位的寄存器.如果用C语言来解释,可以把这些寄存器当作变量看待. 比 ...
- 《汇编语言》第5章 [BX]和loop指令
1.[bx]和内存单元的描述 [bx]是什么呢?和[0]有些类似,[0]表示内存单元,它的偏移地址是0.比如在下面的指令中(在debug中使用): mov ax,[0] 将一个内存单元的内容送入ax, ...
- 汇编语言的准备知识--给初次接触汇编者 (1-4) 转载
汇编语言的准备知识--给初次接触汇编者 1 在接触到游戏修改后发现需要很多的汇编知识,于是找汇编基础知识恶补,到网上搜索到一篇不错的文章,给各位想我一样的初学者一起学习! 教程: 汇编语言的准备知识- ...
- 汇编语言的div指令 ax dx bx
被除数32位,则除数应该是16位. 被除数16位,则除数应该是8位. 防止溢出发生! 1.用到ax dx两个通用寄存器来存储被除数.一般是因为被除数大于65535.使用ax存储低位数据,使用dx存储高 ...
- 汇编实验2.2 查找匹配字符串(附有详细注释和源代码和相关知识)
实验2.2 查找匹配字符串 实验要求: 程序接收用户键入的一个关键字以及一个句子.如果句子中不包含关键字则显示'No match!';如果句子中包含关键字则显示'Match',且把该字在句子中的位置用 ...
最新文章
- 基础算法学习(二)_二叉树及应用赫夫曼编码
- [转载] [硕.Love Python] QuickSort(快速排序)
- TED如何和压力做朋友(一)
- 数据库课设——企业员工人事管理系统
- 微信小程序项目实例——印记
- 喜马拉雅FM下载的音频文件保存在哪_怎么导出来
- 通过网线实现两台PC相互通信(并实现访问公网)
- 修改 ubnt 路由器固件
- 【JavaWeb】之富文本编辑器
- 阿里云服务器 远程桌面连接 卡顿
- android和ios系统的内存,为什么说IOS系统的2G运存相当于安卓手机的8G运存
- Android————一个简单的新闻面板
- uni-app 页面生命周期
- 笔记:caffe安装编译,并用ssd gpu训练自己的数据集
- Android仿QQ登录下拉历史列表
- 树莓派搭建 Google TV
- 第3关:利用栈判断字符串是否为回文串
- 【Vivado】clock ip核的使用
- C语言经典例程100例--【例程1~50】
- 肚子都笑疼的爆笑笑话有哪些?
热门文章
- MFC没改啥就断言错误
- Java设计模式------单例模式
- 深入剖析Redis高可用集群架构原理
- Kubernetes持久化方案(PV、PVC、StorageClass)
- element ui中动态合并单元格_element ui单元格的动态合并
- View.Post()保证UI带你装逼带你飞
- 4种方案,帮你解决Maven创建项目过慢问题
- FFmpeg总结(十四)FFmpeg如何解析直播点播m3u8
- matlab改进 otsu法,otsu算法---matlab实现,和一种改进算法
- linux虚拟机头文件快捷键,linux学习笔记——基础命令、快捷键与认识虚拟机