【知识强化】第四章 指令系统 4.2 指令寻址方式

那在我们讲寻址方式之前,我们先来看一下,补充的两个知识点,一个呢是操作数的类型,一个呢是数据存放的方式。那么之前我们已经讲过了,操作的类型。那么现在我们来看一下操作数的类型。

那么操作数有哪些类型呢?有常见的这四种类型。分别是地址、数字、字符和逻辑数。那么地址是什么呢?地址呢它实际上也可以看作是一种数据。比如在跳转指令当中,那么这个跳转指令的操作数,它就是一个地址。那么绝对地址呢,我们就可以看成是一个无符号的整数。那么相对地址,我们可以看作是一个有符号的数。但是一般来说,地址呢都是一个无符号的整数。那么地址计算呢我们就要在下面的寻址方式当中详细地来介绍。那么数字,数字是最常见的一种类型了。它有定点数、浮点数还有十进制数,我们这些呢,都已经在之前的第二章中做了详细的说明了。字符我们也已经讲过,字符呢,它也可以看做是一种常见的数据类型,一般来说,普遍的是采用ASCII码来表示的。那么逻辑数,就是计算机的另一种运算。逻辑运算当中,这n个0和1的组合呢,它不是看成一个算术的数字,它是被看成逻辑数的。那么这是四种常见的操作数的类型。

那么我们来看一下,在计算机当中是如何存放这些数据的。假设啊我们这是一个数,1、2、3、4、5、6、7、8、H。那么前面的也就是1、2开头的这些呢是它的高位部分,而8、7这些是它的低位部分。

那么存放这些数呢有两种方式,第一种方式呢就是这个样子,1、2、3、4、5、6、7、8,那么这一种方式呢就是说我们的字地址是我们的高字节的地址。那么这种方式就是大端方式。那么字地址呢就是说我们把一行就看成是一个字,然后呢它的地址就是0,如果是字节的话是0、1、2、3,所以呢它的这一行它的地址呢就是字地址就是0。那么第二行呢如果是按字节编址的话就是4、5、6、7,所以呢它的这个字地址就是4。那么如果字地址呢是高字节的地址就是这个样子存放的,1、2、3、4、5、6、7、8,它就是大端方式。如果是7、8、5、6、3、4、1、2这样进行存放呢,也就是字地址是我们的低字节的地址的话,那么这种方式就是小端方式。那么这两种方式呢我们在之前也已经讲过了,想必大家已经很熟悉了。

我们再来看一下,这是一个存储器的一个模拟的样子。我们这一个单元,把它看成呢是一个字节的存储单元。那么这一行我们把它看成是一个字的存储单元,也就是呢我们一个字是32位,如果我们的机器字长是32位的话,所以呢我们一个字就是32位,所以呢就是4个字节。这一行就是一个字,就是32位,4个字节。那么按字节编址,刚才我们已经说过了,就是说每一个字节,存储单位都有一个地址编号。那么按字节寻址的话就是给出一个字节地址,可以取出的长度呢就是一个字节的数据,那么这个字节寻址呢就是这个样子。我们假设一个数据的长度是4个字节,那么我们就需要给出4个字节地址,那么就是像普通所画出的这个样子。每一个字节存储单元呢都有一个地址编号。那么给出一个字节地址的时候就可以取出长度为一个字节的数据,如果这个数据的长度呢是4个字节,我们就要给出这4个字节的地址。

那么按照字地址寻址,也就是说和字节地址寻址呢是不一样的,它是按照字地址寻址的。也就是我们给出一个字地址,就可以取出长度为一个字的数据,就是我们用蓝色框框框出来的这部分。就是我们给出这一个字的地址的话,我们就可以取出长度为一个字的数据。字地址呢我们刚才已经说过了,我们按字节编址的话就是0、1、2、3,所以0~3就是一个字,所以呢每个字当中的最小的字节的地址呢就是它的字地址。

 

那么我们进入本章当中最重要的一节,也就是寻址方式。那么在介绍寻址方式之前,我们先思考这样的一个问题,并带着这样的一个问题进行我们的学习。为什么在指令当中要设置这么多种的寻址方式呢?

那么我们首先来看一下什么是寻址方式。寻址方式指的是寻找指令或者操作数有效地址的方式,所以它叫做寻址方式。那么它的意思是什么呢?也就是说确定本条指令的操作数的地址,或者呢下一条想要执行的指令的指令地址。所以呢我们就可以把寻址方式分成指令寻址和数据寻址。

那么我们这一节呢,首先来看一下比较简单的指令寻址。

那么指令寻址呢,是这样的。我们要注意,就是说我们的所有的指令的地址,总是保存在我们的PC当中的。所以呢,不管是哪种指令寻址方式,我们的这样的指令地址都是由PC给出的。那么指令寻址可以分成两种,一种呢叫做顺序寻址。那么听它的名字就知道,什么叫顺序寻址呢?也就是说我们的程序计数器,也就是PC,它自动加1,那么自动地形成我们的下一条指令的地址。也就是说把PC当中的内容加上1,再送到PC当中,那这就是我们的顺序寻址。那么这里要注意的是,这里加1,它永远都是加1嘛。在任何一台计算机,或者说在任何一个指令集当中它都是加1吗?这是不一定的。我们假设我们的内存单元是按照字节进行这样的一个编址单位的,如果我们的指令它是32位的,也就是四个字节,这时候我们就不是加1了,它是加4。如果我们的指令是64位的,这时候就是加8。那如果我们的这样的指令它是可变长的,这时候呢这样的加1就更为复杂了。那么为了我们方便理解,我们还是记住就是指令寻址,它的顺序寻址还是PC当中的内容加1然后送到PC当中,记住这个就可以了。

那么什么叫做跳跃寻址呢?跳跃寻址是说,我们听它的名字它叫跳跃,那么为什么叫跳跃呢?它是通过我们的转移指令给出的。那么这时候我们的下一条指令的地址码,它不是由程序计数器给出的,而是由我们的本条指令给出下一条指令的地址的计算方式,是由本条指令给出我们下一条指令,所以呢这就叫做跳跃寻址。

对我们来说可能比较抽象,我们来看一个例子吧。假设这是一个指令寻址的过程。那么这时候给出的呢是一个二进制码,

我们呢把它写成汇编语言的形式,这样呢就比较容易理解。

前面呢就是我们的操作码,后面呢就是我们的地址码。首先,我们给这样的指令地址给它编址,

我们为了讲解的方便,编成0到8,这就是我们的指令地址。也就是说我们的第一条指令它的地址呢是0,第二条指令它的地址呢是1,就是这样的指令地址,后面呢就是这条指令它的具体的内容。

首先我们要取第一条指令,这时候呢,我们PC当中就是0。启动机器,它自动运行之后,

 

那么我们上一节课已经把指令寻址讲完了,有两种方式。一种呢叫做顺序寻址,一种呢叫做跳跃寻址。那么在这一节课,以及接下来的课程当中呢,我们将要讲解数据寻址。那么我们在上一节课已经讲过了什么叫做数据寻址。数据寻址就是指确定本条指令的数据地址。也就是说,我们要如何在指令当中表示一个操作数的地址。如何用这种表示得到操作数,或者说怎样计算出操作数的地址。那么这就是我们数据寻址所要讲全部的内容。

那么我们来看一下,我们的一条指令呢,分为操作码和地址码。那么像这样的表示方法呢,我们叫做一地址指令。那么我们知道,我们在这几节课当中将要讲解的数据寻址是非常多的,多达十种。那么如何来确定我们是要用哪一种方式去寻址呢?

那么这时候,为了区别这么多种方式,我们呢就把这几种寻址方式呢给它编个号。当然了这个号码呢是我们给出来的,规定在我们的计算机中就是这样编号的,只是为了帮助大家理解,我们把这几种号码把这几种寻址方式呢编成这样的号码。然后,就可以用这些号码来区分各种的寻址方式。那么我们计算机也就能够知道用什么方式去寻址。那么这时候我们就要在这样的指令当中给一个东西,叫做寻址方式位。

在加载当中,这时候呢我们这样的寻址方式位,也就是我们的寻址特征,这时候就可以来区分我们要用哪一种方式来寻址。那么我们就给出了我们这样的数据寻址的这样的指令格式,是这样的。也就是一个操作码,一个寻址特征,一个形式地址。那么什么叫做形式地址呢?听它的名字就知道,形式地址并不是真正的地址。形式地址就是我们这一条指令字当中的地址。然后我们如何来得到这样的真正的地址呢?什么叫做真正的地址呢?就是我们要找的这样的存储单元,或者说这样的寄存器,这样的地址呢就是我们真正的地址,

我们把它叫做有效地址,也就是我们的操作数的真实地址,它是怎么来得到的呢?它就是通过我们的寻址特征和我们的形式地址,通过它们进行运算,或者通过它们进行转换,然后由形式地址得到我们的有效地址。也就是说寻址特征是什么?寻址特征就是我们为了区分各种寻址方式然后在我们指令字当中设了一个字段。然后通过这样的寻址特征我们知道了要用哪一种方式来寻址。然后根据我们的寻址方式然后再根据我们指令字当中这样的一个地址,也就是我们形式地址,通过这两个结合起来,通过某种运算啊,我们接下来要讲的这几种寻址方法它是怎么来寻址的,然后就可以得到我们操作数的真实地址了。那么这就是我们数据寻址我们约定的一个部分。那么为了使我们的讲解方便,也为了使我们的理解方便,我们约定我们的指令字长=存储字长=机器字长。啊这个我们之前已经讲过了。

那么刚才这是我们的一地址指令。它是由操作码、寻址特征和我们的形式地址。如果把它拓广一下,它是一个二地址指令,还是一样的。不管它是几个地址,它的地址都要给出寻址特征和形式地址。也就是说我们不知道你要用哪一种方式去寻址,所以我们必须要在每一个寻址地址之前都要告诉你我是用什么寻址特征来去寻址的。所以呢二地址指令它的格式就是这个样子的。也就是寻址特征,形式地址,寻址特征,形式地址。那么我们通过寻址特征和形式地址,求出的呢就是我们操作数的真实地址,我们把它叫做有效地址EA。

那么我们来看第一种寻址方式,

叫做隐含寻址。那么什么叫做隐含寻址呢?这一种寻址方式,其实呢我们在之前已经碰到过。我们之前在讲单地址指令的时候就已经讲过了,它是干嘛的呢?它就是说我们这一条指令啊,它不是明显地给出我们操作数的地址。我们在指令当中隐含着我们操作数的地址。

什么叫做隐含着呢?那么这个是什么意思呢?我们之前在讲单地址指令的时候我们讲过,就是说我们不明显地指出我们第二个数的地址,第二个操作数的地址。也就是说我们已经隐含地告诉你,我们的第二个数的地址,它的地址就是累加器。也就是说我们是隐约地规定了这样的一个东西,那么也就是说我们单地址指令啊有一个操作数我们给了一个地址了。那么第二个操作数的地址呢,我们不是明显地给出来,不是告诉你它在哪儿,而是说就是隐含在我们的ACC当中。虽然它是一个单地址指令,虽然它只有一个地址,但是我们第二个操作数的地址已经隐含地给出了,它就是在ACC当中,也就是在累加器当中。所以呢我们的指令格式,只给出了第一个操作数的地址。那么累加器对于我们的这样的单地址指令格式来说,它就是一个隐含寻址。那么隐含寻址大家应该都搞清楚了,就是说我们虽然只有一个单地址指令,但是呢我们的第二个操作数它的地址已经隐含地告诉你,它就是说它就是累加器。

那么它有什么优点呢?优点就是说它缩短了指令字长。因为我们现在只有一个地址,单地址指令嘛。缺点就是说我们需要增加存储操作数或者说隐含地址的这样的一个硬件。就比如说我们这里的ACC,它就要增加一栏告诉你它里面保存的是第二个操作数的地址。所以呢隐含寻址,这个呢大家了解一下即可,隐含寻址不是我们的重点。大家知道一下什么是隐含寻址就可以了。

那么接下来要讲的呢是一个叫做立即寻址。那么我们刚才已经给出了我们数据寻址它的这样的一个指令的指令格式。那么现在我们最简单的一种方式是什么呢?我们就把操作数直接放到形式地址那一边就可以了。也就是说我们不用去取操作数,我们的操作数就在指令当中给出来了,所以这时候,这种方式就叫做立即寻址。

那么立即寻址它的指令特征是什么呢?是一个#号键,#号键就代表了这是一个立即寻址的寻址特征。也就是说这时候我们采用的寻址方式呢是立即寻址寻址方式。也就是说我们这时候形式地址是什么?形式地址它不是地址,它直接把操作数给出来了,也就是0000011。我们采用的呢是补码的方式进行存放。

所以呢立即寻址,定义已经给出来了。形式地址A就是操作数本身,又把它叫做立即数,一般采用补码形式。我们这时候呢,立即寻址特征就是这个#号键。

那么我们来看一下它的访存的次数。我们之前已经约定了我们的指令字长等于我们的存储字长等于我们的机器字长。所以这时候我们取指令只要访存一次就可以了。所以我们取指令访存一次。那么还需要干什么呢?就不需要了。接下来直接把这个取指令就已经给出来了。执行指令的时候因为我们的数就在这儿,我们不用再去取数了,所以我们执行指令访存0次。我们如果不考虑存结果的话,这时候我们共访存。如果我们不考虑存结果的话,我们这时候共访存一次就可以了。

所以它的优点是显然易见的,就是说指令的执行阶段呢它是不访问主存的,所以它的执行时间是最短的。因为我们的数已经在这儿了,我们不需要再到主存里面去访存,去取数。所以这时候呢我们直接把指令取出来之后,操作也有了,数也有了,所以我们的执行时间是最短的。

但是它有一个坏处,坏处就是说因为我们的数,是在我们的指令里面的。这时候A的位数就限制了我们立即数的范围。如果这时候我们形式地址A是n位的话,并且我们的立即数是采用补码的形式的话,我们在第二章讲这个范围的时候它的范围就是-2^(n-1)~2^(n-1)-1。所以它的位数是由我们形式地址的位数所限制的。而我们知道我们的指令就这么长,我们还要腾出一部分来给你,表示一个数。所以我们的数的范围是比较小的,所以这就是我们的一个缺点。那么这就是我们的立即寻址。那么我们这时候想到,如何解决这个呢?我们这时候就不把数放在这个指令当中了,我们就把它的地址放到指令当中,那么这时候这种方式呢就叫做直接寻址。

那么什么叫做直接寻址呢?我们这时候呢寻址特征,根据题目当中的不同而不同,这时候我们就不给出了。我们现在,这时候我们的形式地址A它的地址是什么呢?就是真实地址,也就是我们的EA=A。也就是说这时候我们不是存数了,而是存一个地址。但是这时候存的地址是什么呢?存的地址就是它的真正的地址,所以这就叫做直接寻址。那么它如何去取出这样的数呢?

我们有了这个地址直接到主存当中,把这个A然后所对应的主存的地址把它取出来就可以了,那么这就是直接寻址。所以呢它总共要访问主存几次呢?

首先,取指令一次,执行指令还要有一次。执行指令就是到我们主存里面去取这个数嘛,所以还要再访问一次,所以一共访存了2次。所以它的过程大家有没有理解清楚了。也就是说它的形式地址就是我们的真正的地址。所以我们有了它真正的地址之后,我们直接到主存当中去找到这个真正的地址,然后找到这个地址所对应的操作数就可以了。所以这就叫做直接寻址。

它的优点也就显而易见了。它就是说很简单,执行阶段呢只要访问一次主存就可以了,而且不用专门地去计算我们的操作数的地址,所见即所得。我们的这里的地址就是我们真正的地址,我们根据这个地址到主存当中去访存就可以了,所以它很简单。

但是它的缺点是什么呢?缺点就是说A的位数决定了这个操作数的寻址范围,并且它的这个地址呢不易修改。因为它是一个直接地址,它是一个真正的地址嘛,所以就不太容易修改,是什么就是什么。

那么如何解决这个问题呢?接下来就是我们的间接寻址。那么什么叫做间接寻址呢?顾名思义就是说我们这时候给出的地址并不是我们操作数真正的地址,所以呢间接寻址就是说虽然这时候形式地址还是给出的地址并不是一个数啊,它还是给出的地址。但是它给出的地址呢,不是我们操作数真正的地址,而是说我们操作数有效地址所在的地址。换句话说就是说,我们操作数地址的地址。所以呢我们给出表达式就是EA=(A)。也就是说我们这时候A给出的呢是操作数的地址的地址。什么意思呢?

就是说现在,我们这时候有了一个A。我们这个A呢到主存当中去访问主存A所在的这个单元,这时候访问到的如果是直接寻址的话,我们这时候A里面存放的就是我们的数。但是并不是的,这时候我们是间接寻址。这时候A里面存放的是什么呢?A里面存放的是我们操作数所在的地址,所以呢我们有了这个地址之后,我们还要再到这个EA当中,主存当中,主存的EA这个地方再去取我们的操作数。也就是说这时候我们的有效地址是由我们的形式地址间接提供的,所以呢这就叫做间接寻址。图中给所给的这样的呢是一次间址,就是说A地址单元的内容呢它是EA。EA呢,是我们操作数的它的地址。啊,这是一次间接寻址。

它一共访问了几次呢?取指令是一次,那么执行指令呢我们要访存两次。第一次呢是到主存当中找到A这个地方,A这个地方呢取出来的是EA。然后再去EA当中取出我们的操作数,这时候呢一共访存了三次。

那么这叫一次间址,那么还有多次间址。比如说这个就是我们的两次间址。两次间址首先,当存储字首它的首位是1的时候,表明我还要继续去访问我们的存储单元,然后继续去寻址,所以呢我们先得A,取出A1。然后取出A1之后,我们再到A1这个地方来再取出EA,然后再到EA当中去取出我们的操作数。这时候呢就是我们的两次间址。所以呢这就是我们间接寻址它的方式。大家应该也很容易理解。它和直接寻址不一样,直接寻址我们的这时候的形式地址已经是我们的真正的地址了,而这时候我们间接寻址呢我们形式地址所给出的呢是操作数地址的地址。我们还要再到主存当中取出我们的地址,然后再根据这个地址去取出我们的操作数。所以呢间接寻址是这个样子的。

优点就是说,我们扩大了寻址的范围。为什么呢?因为我们A的位数通常是小于指令的字长的。而我们的存储字长呢是和我们的指令字长相等的。你比如说我们的现在的指令字长和我们的存储字长呢都是16位,如果A是8位,所以呢这时候我们的直接寻址范围是2^8。但是如果我们现在是一次间接寻址,这时候我们的寻址范围可以达到2^16。如果多次寻址的话,我们的范围呢,还会继续扩大。那么第二个它的好处就是说,便于编程。因为我们可以看到这样的寻址方式和我们的子程序调用返回它是非常像的,所以呢就可以用我们的间接寻址方便地完成我们的子程序的返回。啊大家这个了解一下就行了。

 

 

但是它的缺点很容易看到就是说,我们在执行阶段要多次访存,所以呢我们的执行时间是会变长的。所以,这就是我们的间接寻址。那么我们之前这几种方式呢都是跟我们的主存在打交道,那么我们在计算机当中除了有主存,还有一个东西叫做寄存器。

 

下面我们来介绍两种寄存器有关的寻址。第一种就叫做寄存器寻址。那么寄存器寻址呢就是说我们指令字当中直接给出的呢是操作数所在的寄存器的编号。也就是说,我们的形式地址给出的呢是我们的寄存器的编号,我们的操作数所在的就是在我们的寄存器当中。所以这个寄存器呢就,它里面存放的呢,就是我们的操作数。

 

 

我们来看一下示意图,就是这个样子。我们这时候形式地址存放的是Ri,然后我们根据这个Ri啊,这个Ri,这个寄存器里面存放的呢,就是我们的操作数,还是很简单的。这和直接寻址是差不多的,只不过把直接寻址里面的主存换成了我们的寄存器,也就是说我们的寄存器的编号,这时候就是我们的形式地址。我们根据我们的寄存器的编号,去到第几个寄存器当中去取出我们的操作数就可以了。

所以呢,它一共要访存几次呢?首先取指令要访存一次,执行指令不需要访存,因为我们的寄存器是直接在我们的CPU里面的,我们不需要再去主存里面去访问我们的操作数了。所以这时候呢,我们只需要访问一次就可以了。

 

 

它的优点是显然易见的,很快嘛,所以嘛所以就是说,我们的指令它在执行阶段是不需要去访问主存的,只需要去访问寄存器就可以了。所以呢指令字而且短,因为我们的寄存器的个数是有限的,形式地址给出的呢是我们的寄存器的编号。编号总共就那么多,所以呢我们的指令字它就短了,并且呢执行速度也就快了。并且呢它还能支持我们的向量和矩阵运算,啊这个我们了解一下就可以了。关键一点就是说它很快,并且呢寄存器的个数是有限的,所以呢也就节省了我们的这个储存空间、存储空间,所以呢寄存器寻址在计算机当中呢是得到了一些广泛的应用的。

 

 

缺点是什么?因为我们的寄存器的价格是比较昂贵的,并且寄存器的个数也是有限的,所以呢这就是它的缺点。那么如何解决这个问题呢?我们就把寄存器和我们的主存结合起来,那么就是我们的寄存器间接寻址。

 

那么我们上一节课已经介绍了6种寻址方式,那么我们这一节课再来介绍三种偏移寻址的方式。

我们首先回顾一下上一节课的内容。上一节课我们讲了些什么呢?我们讲了就是说在数据寻址当中呢?我们的指令格式是这个样子的。我们有一个寻址特征。寻址特征是用来干什么的呢?是用来区分我们是属于哪一种寻址方式的。然后形式地址是用来干什么的呢?形式地址就是用来和寻址特征一起求出我们的真实地址的。那么我们上一节课已经介绍了隐含寻址,立即寻址,直接寻址,间接寻址,寄存器寻址和寄存器间接寻址。那么我们这一节课将要讲解三种偏移寻址方式,也就是基址寻址,变址寻址和相对寻址。我们下一节课将要讲最后一种堆栈寻址方式。

那么什么叫做偏移寻址呢?偏移寻址,听它的名字就应该知道,就是有一个偏移量,然后再加上一个我们的形式地址,然后得到我们的真实地址。所以它们的格式都是一样的。

都是这个样子。EA,EA是什么?EA就是真实地址,等于一个东西加上我们的形式地址。它们的形式都一模一样,所不同的呢,就是前面加的这个东西不同。

那么首先我们来看基址寻址,那么什么叫做基址寻址呢?基址寻址就是说我们CPU当中有一个寄存器它叫做基址寄存器BR,它里面的内容呢加上我们的形式地址,形成我们的有效地址,也就是EA=(BR)里面的值再加上A,我们的形式地址。也就是说,我们这时候的偏移量呢就是我们的BR。

这时候我们把这个BR叫做B地址, 也就是说我们的基址寄存器里面的这个东西,它里面存放的东西叫做B地址。然后和我们现在,我们的指令当中的,这个形式地址进行一个加法,然后得到的就是我们的真实地址。根据我们的真实地址到我们的主存当中去找我们的操作数。所以呢,这就叫做基址寻址。那么过程就是这个样子,其实也很容易理解啊。就是有一个专门的寄存器叫做基址寄存器,它里面存放的呢叫做基地址。基地址和我们的这个形式地址加在一起得到的就是我们的真实地址。那么基址寄存器有两种形式,一种呢叫做显式的,一种呢叫做隐式的。那么我们现在屏幕当中所展现出来的呢,就是一个叫做隐式的这样的形式。什么叫隐式呢?就是说我们现在计算机当中,专门的有一个寄存器,叫做基址寄存器BR。也就是说我们使用的时候,用户不必要明显地指出这就是一个基址寄存器。我们只需要根据我们的指令的寻址特征位,也就是我们刚才之前就讲过的啊那个寻址特征位反映出它就是一个基址寻址就可以了,我们这时候用户不必要指定哪一个是基址寄存器。我们的基址寄存器呢已经有了专门就有它,我们不需要单独地、特地地把它明显地指出,我们就已经有它了。所以呢我们只需要根据我们的特征位,反映出这是一个基址寻址就可以了。那么显式的是什么意思呢?显式的,和隐式的正好相反。刚才说我们已经有了一个专门的寄存器叫基址寄存器了。我们用户呢就不需要明显地去指出了,这时候显式的就是说我们用户需要指定哪一个寄存器是基址寄存器,就是这个样子。

那么我们是有一组通用寄存器的。然后呢,在这一组通用寄存器里面,我们用户去指定哪一个作为我们的基址寄存器。然后它里面呢放的呢是我们的基地址。就比如说,像图中所给的这个样子。我们这时候呢,就要把我们的R0,把它标出来,告诉它R0这时候做的是基址寄存器。然后呢,R0里面存放的呢,就是我们的基地址。所以呢,两个有什么有不同?一个呢是有一个专门的寄存器叫做BR,它就是基址寄存器。所以呢,它是隐式的,因为我们不需要明显地去指出它,我们只需要通过寻址特征告诉这个计算机我这时候用的呢是基址寻址就可以了。但是第二种呢就是没有一个专门的寄存器,它是通用寄存器里面我用户去指定哪一个作为我们的基址寄存器。然后呢必须地明确地指出,比如说这时候我们指出R0它是一个基址寄存器,它里面存放的呢就是我们的基地址。所以这两种,就是这个区别。

所以大家应该清楚什么是基址寻址了。很简单,就是基地址加上我们的形式地址得到我们的有效地址。那么基址寄存器啊,它是面向操作系统的,它的内容呢是由我们的操作系统或者呢管理程序来指定的。它里面的内容,啊它是由操作系统和管理程序确定的,不是我们用户确定的,是由操作系统它确定的。那么在程序执行过程当中呢,基地址它的内容呢是不变的,而形式地址它是一个偏移量,偏移量肯定是可以改变的。所以呢就是这样一个好处,就是说我们的用操作系统来指定我们的B地址,它是不变的,而我们的A它是可以改变的,因为它是一个形式地址。那么它的好处呢,我们就要在下面来讲。

如果我们现在采用通用寄存器作为我们的基址寄存器,也就是说我们用户决定哪一个是我们的基址寄存器。这时候它的内容,它里面的内容啊,还是由我们操作系统来确定它里面放什么内容,而不是说我用户说基地址是多少,不是的,是操作系统说基地址是多少。但是用户是什么呢?用户是决定哪一个寄存器作为我们的基址寄存器,啊这是不一样。它里面的这个内容,都是由操作系统或者我们的管理程序来确定的,是不变的。

那么刚才我们也讲到了它的优点,优点就是说我们有一个是基地址,它是不变的。而有一个这个形式地址A它是作为偏移量是可变的。那么它带来的好处就是说我们用户不必要考虑自己的程序存在于主存的哪一个空间,我们是有利于我们的多道程序来设计的,所以呢可以用于一个编写我们的多道程序还可以编写我们的浮动程序。因为它是有一个基地址,还有一个偏移量。那么具体是什么,我们在下面来讲。然后还有一个就是我们的扩大寻址范围。扩大寻址范围呢就是说由于我们的基址寄存器,它的位数啊,它是可以大于我们这个A的位数的。所以呢,当主存容量较大的时候,如果采用直接寻址的话,直接寻址是什么意思大家应该很熟悉了吧。直接寻址就是说我们的形式地址就是我们的操作数的地址。如果用直接寻址的话,A它的位数有一个限制,无法对我们的主存的所有的单元进行访问。但是呢,用这个基址寻址我们就可以实现对我们的主存的更大的范围进行访问,因为它是一个BR它的内容加上A啊。所以我们的主存空间就有一个更大的一个范围,我们的基址寄存器的位数它是可以大于我们A的位数的,所以我们的范围就进行了扩大。就比如说我们如果将主存空间分成一个若干的段。每一个段首的地址,存放在我们的基址寄存器当中。段内的偏移量,是由我们的A指出的。所以呢这时候我们操作数的有效地址就等于我们的基址寄存器的内容,再加上我们的段内偏移量,这样的和。我们只需要对我们的基址寄存器里面的稍作修改,就可以访问我们的主存的任意一个单元,所以这时候就扩大了一个寻址的范围。

那我们再来看一下什么叫做有利于多道程序的设计。这个图大家在学习操作系统的时候应该经常看过,啊这是我们在计组当中把它拿过来,帮助我们理解的。注意接下来讲的内容大家听不懂就算了。因为这时候不是考试的重点,只是为了帮助你理解。你能理解更好,你如果实在理解不了的话,你就记住,它的优点就是说有利于多道程序的设计,有利于编写浮动程序,用户不必要自己考虑我们的程序放在主存当中哪一个区域。因为它由操作系统来决定了嘛,所以我们就有利于多道程序设计,为什么啊。

首先我跟你讲为什么。比如这时候有这样的一个程序,这是一个循环的结构。如果现在我们要程序,我们计算机要执行这一段程序,首先要把它转换为机器指令去执行。但是呢,为了我们能够理解,我们先把它转换为汇编代码。

汇编代码

 

那么我们最后来看一下堆栈寻址的内容。这一块内容呢比较简单,也不是重点。

我们先来复习一下我们之前已经讲过的九种,隐含寻址、立即寻址、直接寻址、间接寻址、寄存器寻址、寄存器间接寻址。然后就是我们上节课讲的那三种,偏移寻址也就是相对寻址、基址寻址和变址寻址。那么之前我们在讲隐含寻址的时候是说,有一个操作数是隐含的了,比如说是放在ACC里面。还有一个操作数呢它的地址要给出来,但是我们的堆栈寻址呢就不一样,它呢两个操作数都可以隐含起来。那么是如何来实现的呢?

那么就是由堆栈来实现的。那么什么叫堆栈?大家在数据结构当中应该都已经掌握过了,我这里就不再赘述了。堆栈就是一个后进先出的一个存储区,啊堆栈它就是后进先出。大家在数据结构当中应该已经很了解这个东西了。

它是在存储器,或者呢是我们的专用的寄存器组当中,按照这样的一个原则管理了一块存储区。并且呢,它这个存储区当中,被读或者被解的单元的地址呢,是用一个特定的存储器给出的。那么这个存储器叫做堆栈指针SP。也就是说我们整个操作数是放在我们堆栈当中的,并且隐含地用我们的堆栈指针SP作为我们的操作数地址。

我们给出一个示意图。假设这四个寄存器就是一个堆栈,R0、R1、R2和R3。然后我们的堆栈指针就是由一个寄存器来表示的。

 

 

因为我们现在是四个寄存器嘛,所以呢我们就用两位数字来表示就可以了,00、01、10和11。

 

 

然后呢我们的SP是指向我们的栈顶元素,这时候我们指向的是R0,然后R0呢就是一个栈顶。那么接下来,如果我们要进行运算的话,是如何运算的呢?

 

 

我们假设,我们要进行一次加法运算。

那么我们首先记我们的栈顶单元呢是Msp,那么首先第一步就是POP。POP是什么意思啊,就是出栈,也就是把Msp里面的内容放到我们的ACC里面。那么Msp它里面的内容是什么呢?就是我们的0001,

 

所以我们ACC里面就是0001。

 

接着我们这个栈顶指针啊,它要加1。

 

然后呢,它里面就变成了01,就指向了我们的R1这个单元。

 

所以这时候呢,接下来还是POP。

 

然后就是把Msp放到X。

 

posted on 2019-09-08 08:01  绿茵好莱坞  阅读(1031)  评论(0编辑  收藏  举报

导航