汇编基础知识(二)

一、通用寄存器

对于一个汇编程序员来说,CPU中主要部件是寄存器。寄存器是CPU中程序员可以用指令读写的部件。程序员通过改变各种寄存器的内容来实现对CPU的控制。

不同的CPU,寄存器的个数、结构是不同的。8086CPU 有14个寄存器,每个寄存器有一个名称。这些寄存器是:AX、BX、CX、DX、SI、BP、IP、CS、SS、DS、ES、PSW。在今后的学习中我们用到这些寄存器时就对这些寄存器进行介绍。

AX、BX、CX、DX四个寄存器可以存放一般性的数据,所以这四个寄存器称为通用寄存器。在8086CPU中,寄存器都是16位的,可以存放两个字节的数据,所以表示的最大值是2^16-1。

8086CPU的上一代CPU使用的是8位的寄存器,所以为了保证程序的兼容性,使的针对上一代CPU开发的汇编程序能够在8086CPU上运行,8086将通用寄存器分成两个8位的寄存器:

  • AX可以分为AH和AL
  • BX可以分为BH和BL
  • CX可以分为CH和CL
  • DX可以分为DH和DL

以AX为例,如上图所示。AX的0~7位为AL,8~15位为AH。对AX中存放的数据有两种解释方式,如果是看做16位的AX则表示20000,如果看做8位的寄存器,则AH表示78,AL表示32。

二、几条汇编指令

下面我们来看一下汇编中两个最常用的指令mov和add,下表展示了它们的用法。

注意:汇编指令是不区分大小写的,所以写成ADD AX,8和add ax,8的效果是一样的。

我们结合着刚刚讲过的寄存器来看一下汇编指令是如何改变寄存器中的内容的。

我们假定开始时,AX和BX中的数据都是0000H。

现在我们来分析一下最后的?是怎么回事。最后一条指令执行之前AX=8226H,BX=8226H,如果执行ADD操作,则A的值应该是1044CH,但是AX是16位的寄存器,最大值就为FFFFH,所以超出16位的部分就会被省略,所以AX=044CH。

再来看看对AH和AL的操作实例:

我们还是假设,开始时AX和BX中的数据为0000H。

下面来看一下最后的?应该是什么值,ADD AL,93H执行后AL的数值为158H,但是AL为8位寄存器最大只能存储FFH,所以超过8位的部分会自动省略,于是AX中数据就变成了0058H。

三、物理地址的形成

8086CPU是16位的结构,这就意味着字长是16位,寄存器的最大宽度为16位,运算器一次可以处理16位的数据,寄存器和运算器之间的数据通路为16位。

然而8086CPU却有20位地址总线,可以传送20位地址,所以能够达到1MB的寻址空间,但是由于是16位架构的CPU,所以如果仅仅从CPU内部简单的将地址送出则只能形成16位的地址,寻址能力也只有64KB,这可咋办呢。

为了解决上述问题,8086CPU采用了一种使用两个16位地址合成一个20位地址的方法来形成一个20位的物理地址,从而扩大了寻址能力。

物理地址=段地址*16+偏移地址

地址加法器采用物理地址=段地址*16+偏移地址的方法用段地址和偏移地址合成物理地址。例如,8086CPU想要访问123C8H的内存单元,此时,加法器就利用1230H和00C8H两个地址形成123C8H这个地址。

我们可以用一个简单的例子来描述一下这个思想,如下图所示,假如学校、体育馆和图书馆的位置如下:

假如你有一张可以写4位数的纸条,那么图书馆的位置可以被表述为2826,如果不幸你没有4位的纸条只有两张三位的纸条,那么图书馆的位置就必须借助上面的思想,我们可以用200和826两个三位数字来表示,图书馆的位置就在200*10+826=2826m上。

四、段寄存器

上面我们一直说段地址,但实际上内存中并没有分段,段的划分来自CPU,由于8086CPU用基础地址(段地址)*16+偏移地址=物理地址的方式给出内存的物理地址,使得我们可以用分段的方式来管理内存。我们可以认为10000H~100FFH的内存单元为一个段,段的起始地址是10000H,段地址为1000H,大小为100H;我们也可以认为10000H~1007FH、10080H~100FFH的内存单元组成两个段,它们的起始地址为10000H和10080H,段地址为1000H和1008H,段大小为80H。

既然地址加法部件要用段地址和偏移地址形成物理地址,那么这两个地址就必须都被保存下来。8086CPU有四个段寄存器:CS、DS、SS、ES。

CS和IP是8086CPU中两个关键的寄存器,他们指示了CPU当前要读取指令的地址。CS为代码段寄存器,IP为指令指针寄存器。如果CS中的内容为M,IP中的内容为N,那么CPU就将从内存M*16+N单元开始,读取一条指令并执行。也可以表述为如下:

8086机中,任意时刻,CPU将CS:IP指向的内容当做指令执行。

下面通过一组图的方式展示8086CPU读取、执行一条指令的过程。

初始状态,CS:2000H,IP:0000H。

地址加法器利用CS和IP中的地址形成物理地址。

地址加法器将物理地址送入输入输出控制电路。

输入输出电路将地址送上地址总线。

从内存20000H单元开始存放的机器指令B8 23 01通过数据总线被送入CPU

输入输出电路将机器指令送入指令缓冲器。

读取一条指令后,IP中值会自动增加,以使CPU可以读取下一条指令,因为当前读入的指令为3个字节,所以IP的值加3。

执行控制器执行指令。

AX中的内容被改变。

后面的过程与这个过程是相同的,这里不再画出来了,因为文章的篇幅已经很长了。

注意:在8086CPU加电启动后或复位后,CS和IP被设置为CS=FFFFH,IP=00000H,即8086CPU在刚启动时,CPU从内存FFFF0H单元中读取指令执行。

五、修改CS、IP的指令

那么我们是否能够通过指令改变CS和IP的值呢?答案是肯定的,但是不是通过MOV指令,8086提供了单独的指令来改变这两个寄存器的值。

1、若想同时改变CS和IP的值,可以用“JMP 段地址:偏移地址”的指令来完成。

例如:JMP 2AE3:3,执行后:CS=2AE3H,IP=0003H,CPU将从2AE33H单元读取指令。

2、若想仅修改IP的内容,可以使用形如“JMP 某个合法寄存器”的指令来完成。

例如:JMP AX,指令执行前:AX=1000H,CS=2000H,IP=00003H,指令执行后:AX=1000H,CS=20000H,IP=1000H

时间: 2024-08-28 21:13:19

汇编基础知识(二)的相关文章

汇编基础知识二

DEBUG的使用 (要在win32位习题下进行,win7 64位需要安装DosBox和debug这2个软件): 1:win64位下debug的使用教程: 下载debug.exe,这里我把debug放在了c盘根目录下 下载DosBox并安装好, 输入mount c c:\  加载目录到c盘 输入c:\  进入到c盘,看到我们已经在c盘下了. 输入debug,表示打开放在c盘下的debug工具,使用r命令,可以看到,我们进入了熟悉的debug环境. 2:debug的基本命令: R  查看,改变CPU

汇编基础知识

1.SI和DI 功能和bx相似,只是不能分成2个8寄存器使用. 2INC ax指令 将寄存器的内容加1 mov ax,0 inc ax 执行完毕ax=1 3.bx,si,di,bp寄存器 CPU的核心是寄存器,学习汇编这么一段时间,我也深刻体会到对寄存器理解的重要性 (1)在8086CPU中,只有这4个寄存器可以在[...]中来进行内存单元的寻址.比如下面指令是正确的. mov ax,[bx] mov ax,[bx+si] mov ax,[bp] mov ax,[bp+si] mov ax,[b

ASP.NET Core 2.2 基础知识(二) 中间件

原文:ASP.NET Core 2.2 基础知识(二) 中间件 中间件是一种装配到应用管道以处理请求和相应的软件.每个软件都可以: 1.选择是否将请求传递到管道中的下一个组件; 2.可在调用管道中的下一个组件前后执行工作. 管道由 IApplicationBuilder 创建: 每个委托都可以在下一个委托前后执行操作,.此外,委托还可以决定不将请求传递给下一个委托,这就是对请求管道进行短路.通常需要短路,是因为这样可以避免不必要的工作.比如: 1.静态文件中间件可以返回静态文件请求并使管道的其余

Java基础知识二次学习-- 第一章 java基础

基础知识有时候感觉时间长似乎有点生疏,正好这几天有时间有机会,就决定重新做一轮二次学习,挑重避轻 回过头来重新整理基础知识,能收获到之前不少遗漏的,所以这一次就称作查漏补缺吧!废话不多说,开始! 第一章  JAVA简介 时间:2017年4月24日10:23:32 章节:01章_02节 内容:jdk的配置与安装 完成情况:已经完成,cmd中javac提示出相关命令 时间:2017年4月24日10:30:39 章节:01章_04节 内容:输出HelloWorld 完成情况: 已经完成 javac先将

Java基础知识(二)

1,字符串 new String("abc")创建了几个对象? 一个或两个,如果常量池中原来有"abc",则只创建一个对象:如果常量池中原来没有字符串"abc",那么就会创建两个对象. String s="abc"; String s1="ab"+"c"; System.out.println(s==s1); 输出 true ,因为"ab"+"c"

Powershell基础知识(二)

上一节主要介绍Powershell可发现,面向对象,一致性等特性,以及Powershell命令是基于.Net对象等重要概念,以及Powershell命令的命名规范,详细内容点击这里. 这一节的Powershell基础知识主要包含以下知识点 获取命令的摘要信息. 获取命令的帮助信息. 总结. 获取命令的摘要信息 Powershell命令 Get-Command 可检索当前shell中所有可用的命令名称.在Powershell提示符输入 Get-Command ,输出的内容类似以下内容(以下只写出输

计算机科学基础知识(二)Relocatable Object File

一.前言 一个合格的c程序员(也可以叫做软件工程师,这样看起来更高大上,当然,我老婆心情不好的时候总是叫我"死打字的",基本也能描述这份职业,呵呵)需要理解编译.链接和加载的过程,而不是仅仅关注c语言的语法和词法.本文主要以此为切入点,描述linux系统下,一个普通的hello world程序的生命历程,并借机灌输一些程序编译时和运行时的基本术语和概念.当然,由于我本人是一个linuxer,因此借用linux来描述这些知识会方便些,但是对于计算机科学而言,这些东西概念上是类似的,只是实

Java基础知识二次学习-- 第二章 基础语法与递归补充

第二章 基础语法与递归补充   时间:2017年4月24日10:39:18 章节:02章_01节,02章_02节 视频长度:49:21 + 15:45 内容:标识符,关键字与数据类型 心得:由字母,下划线,$,数字组成,应该由字母,下划线$开头,同时应该避开java保留字符 变量是内存中的一小块区域,使用变量名来访问这块区域 执行过程中的内存管理(疑问:这里的内存和Jvm的一样吗?) code segment 存放代码 data segment 静态变量 字符串常量 stack 栈 局部变量 h

jsp基础知识二(jsp动作指令)

动作指令与编译指令不同,编译指令是通知servlet引擎的处理消息,而动作指令只是运行时的动作.编译指令在将JSP编译成Servlet时起作用,而动作指令通常可替换成JSP脚本,它只是JSP脚本的标准化写法. (1)JSP:forward  执行页面转向,将请求的处理转发到下一个页面. (2)JSP:param  用于传递参数,必须与其他支持参数的标签一起使用 (3)JSP:include  用于动态引入一个JSP页面 (4)JSP:plugin 用于下载JavaBean或者Applet到客户端