计算机组成原理 第四章 指令系统

4.1 指令格式

指令是计算机执行某种操作的命令。一条指令就是机器语言的一个语句,是一串有意义的二进制代码,一般为分操作码和地址码两部分。
在这里插入图片描述
操作码指示应该执行什么性质的操作和具有什么样的功能。地址码则指出了被操作信息的地址。简单来说操作码就是做什么,地址码就是在哪里做。

指令的长度指的是一条指令中所包含二进制代码的位数。长度取决于操作码的长度、操作数地址码的长度和操作数地址的个数。指令字长与机器字长没有直接关系,超过机器字长的指令分次取即可。在一个指令系统中如果所有指令的长度都相等则称为定长指令字结构,定长的好处是执行速度快,控制简单。如果指令的长度随着功能而异,则称为变长指令字结构,变长的长度仍为字节的整数倍。

根据地址数的个数,一般将指令分为下面几类:
①零地址指令
在这里插入图片描述
只有操作码部分,没有显式地址。这种指令有两种情况,一种是不需要操作数的指令,另一种是在堆栈计算机内,此时操作数由栈顶和次栈顶的元素来确定。
②一地址指令
在这里插入图片描述
由操作码和一个地址码组成,这种指令有两种情况,一种是目的操作数是单操作数,比如取反、自加等,运算后再存在原来的位置,所以只需要一个地址码就可以解决问题。另一种是隐含目的地址的双操作数,可以隐含约定另一个操作数由累加器提供,这样可以将累加器和地址码上的数据做运算后再放在累加器上。
③二地址指令
在这里插入图片描述
由一个操作码和两个地址码组成,一般将两个地址码对应的位置做运算后再保存在其中一个的地址上
④三地址指令
在这里插入图片描述
在二地址指令的基础上,多一个A3来表示结果存放的地址。
⑤四地址指令
在这里插入图片描述
在三地址指令的基础上,增加一个A4表示下一条指令的地址。

这五种指令,对于定长操作码指令来说,地址越多越不利,因为地址多了只会让指令中出去操作码的部分分给每个地址的位数更少,即寻址范围会变小,如果指令字长是32位,操作码固定8位,零地址指令有24位去寻址,而四地址指令只有6位去寻址,范围差距特别大。

定长操作码的情况下,操作码在高位固定分配固定位数来表示操作码,剩余部分作为地址码来分配。这种方式有利于简化计算机硬件设计,提高译码和识别的速度。

为了在指令字长有限的前提下保证比较丰富的指令种类,可以采用变长操作码,即操作码字段的位数不固定,而是分散地放在指令字的不同位置上。这种方式会增加译码的难度,使控制器的设计更加复杂。

最常见的变长操作码是扩展操作码,这种操作码的长度随地址码的减少而增加,不同地址数的指令可以具有不同长度的操作码,从而在满足需求的前提下有效缩短指令字长。
在这里插入图片描述
图中所示的就是扩展操作码技术,简单来说这种扩展操作码就是利用操作码段不同来表示指令,图里的三地址指令,如果需要15条,那么就分配给4位,但是要留下一个1111来给后序继续拓展,这个过程有点像计算机网络里面的子网划分和最长前缀编码。图中三地址指令为15条,需要留1111来继续扩展,二地址指令为15条,也需要留1111 1111扩展使用,一地址指令为15条,需要留1111 1111 1111来扩展使用,最后的零地址指令不需要再扩展,所以为16条。这种分配并不是固定的,可以根据不同地址数的指令的条数来分配,但是有两点一定要保证:前缀不重复和操作码不重复(二者本质上是一样的,这种扩展操作码实际上就是利用了前缀不同,每一个前缀对应唯一的一个操作)。

4.2 指令的寻址方式

寻址方式指的是寻找指令或者操作数有效地址的方式,即确定本条指令的数据地址及下一条待执行指令的地址的方法。寻址方式分为两类:指令寻址和数据寻址。

指令寻址指的是寻找下一条执行的指令的地址。指令寻址分为两类:顺序寻址和跳跃寻址。顺序寻址通过程序计数器自动加一来得到下一条指令的地址,执行完这条指令后会从PC中得到下一个地址继续寻址。跳跃寻址则通过转移类指令来实现,这种情况下,下一条指令的地址码不由程序计数器给出,而是由本条指令来给出下一条指令地址的计算方式。这里需要注意,跳跃的结果是修改了PC的值,PC在加载完指令后先自加1,然后再跳转到指令中指示的位置。

数据寻址指的是寻找操作数的地址。数据寻址的方式很多,一般在指令单独设一个字段用来指明是哪一种寻址方式。数据寻址总共有下面的十种方式:
①隐含寻址
这种类型的指令不明显地给出操作数的地址,而是在指令中隐含操作数的地址。单地址指令就是很好的例子,其中一个操作数是通过地址给出的,另一个操作数则是隐含的。隐含寻址有利于缩短指令字长,但是需要增加存储操作数或者隐含地址的硬件。这种寻址方式是简化地址结构的基本方法。
在这里插入图片描述
②立即寻址
存放在指令中的地址码字段的不是操作数地址,而直接就是操作数本身,又称立即数。数据本身采用补码存放。这种寻址方式好处在于完全不需要访问主存,但是位数是受限制的,操作数很长的情况下是不能采用这种方式的。
在这里插入图片描述
③直接寻址
指令中存放的形式地址就是真正的地址,直接去形式地址所指示的位置就可以找到需要的操作数。这种寻址方式简单,在执行过程中只访问一次主存,而且不需要进行地址的计算。但是和立即寻址一样也是受限于位数,寻址范围有限。
在这里插入图片描述
④间接寻址
间接寻址是相对于直接寻址而言的,指令中地址码字段指示的并不是操作数的地址,而是存放有操作数地址的存储单元的地址,即操作数地址的地址,套了一层娃。间接寻址可以进行好几次,可以用首位来表示。间接寻址的好处就是扩大了寻址范围,原本A的位数要小于机器字长,而指向的位置的长度肯定要大于A的长度,所以扩大了寻址范围,同时这种方式便于编制程序,因为很方便完成子程序返回,缺点也很明显,需要访问两次主存,从而速度过慢,一般问扩大寻址范围时,一般指的是速度更快的寄存器间接寻址。
在这里插入图片描述
⑤寄存器寻址
指令中直接给出存放有操作数的寄存器的编号,可以看作直接寻址将指向内存换成指向寄存器。这种方式不需要访问内存,而是访问了速度更快的寄存器,而且由于寄存器数目少,所以指令字短而且不用访问内存,从而让速度很快。缺点是寄存器一般价格较贵,寄存器数目有限
在这里插入图片描述
⑥寄存器间接寻址
指令中地址码指向的是存放有操作数在主存上位置的寄存器的位置,相当于将间接寻址中的第一层由指向内存换成指向寄存器。这种方式少了一次访问主存,所以速度更快,但是仍需要在第二次访问主存,根本上就是第一次访问寄存器第二次访问内存,扩大了寻址范围而且第一次访问由于换成了访问寄存器,速度也提升了。
在这里插入图片描述
⑦相对寻址
相对寻址是将PC的值加上指令中的形式地址来得到有效地址,这个形式地址表示的就是一个偏移量,用补码表示,可正可负。这种寻址方式的好处在于操作数的地址不是固定的而是浮动的,这种寻址方式广泛用于转移指令。这个过程一定是先PC自加然后再跳转,题目中如果不注意这一点一定会找错地址。
在这里插入图片描述
⑧基址寻址
基址寻址是指将CPU中基址寄存器的内容加上指令格式中的形式地址而形成操作数的有效地址,基址寄存器是面向操作系统的,内容由操作系统或者管理程序确定,在执行过程中基址寄存器内容不变,通过变化形式地址来变化。基址寻址可以扩大寻址范围,有利于多道程序设计,但是偏移量受限。
在这里插入图片描述
⑨变址寻址
变址寻址是指有效地址等于指令字中的形式地址与变址寄存器的内容之和。变址寄存器面向用户,寄存器内部的内容可以由用户来确定,但是地址不再变化。这种寻址方式好处在于可以扩大寻址范围,一般用于解决数组问题,数组基地址由形式地址给出,具体的偏移量由寄存器给出。
在这里插入图片描述
显然,变址寻址和基址寻址的方式极为相似。从本质上来说,基址寻址面向的是操作系统,用于多道程序或者分配存储空间,程序执行期间基址寄存器中的内容不变而指令中的形式地址可变。变址寻址立足于用户,主要用于处理数组问题,变址寄存器内的内容可变但指令中的形式地址不可变。

⑩堆栈寻址
主要是利用堆栈来暂存数据,可以用于零地址指令,操作数地址隐含使用堆栈,直接可以从堆栈里面取数据。

总的来说,十种寻址方式各有利弊,需要根据题目要求灵活使用,有效地址及访存次数的规律如下:
在这里插入图片描述
这里需要补充一下,对于定长操作码和变长指令码,不同的寻址方式也是有区别的。变长指令码中,寻址方式为寄存器寻址时长度最短,因为寄存器数目较少,寻址所需要的位数也较少。对于需要在内存中寻找的寻址方式位数都比较多,因为内存的范围显然要比内存器大,需要的位数也多。变长指令码采用寄存器寻址更快,但是定长操作码却成了立即寻址最快,这是因为定长的情况下,不管地址还是立即数,都需要读完这条指令才行,寄存器在读完后开始查找寄存器,但是立即寻址读完就知道数据了,所以定长下立即寻址更快,变长时由于寄存器寻址更短,所以会比立即寻址先读完,此时寄存器寻址更快。最慢的肯定是间接寻址,因为需要两次访问内存。

4.3 CISC和RISC

这一节主要是介绍了指令系统的两个发展方向。增强原有指令的功能和简化指令种类和指令功能,二者分别对应CISC和RISC。

CISC全程复杂指令系统计算机,主要特点如下:
在这里插入图片描述
RISC全称精简指令系统计算机,特点如下:
在这里插入图片描述
二者对比如图所示:
在这里插入图片描述

典型题

在这里插入图片描述
这类题考察扩展操作码的扩展方法,三地址指令有29条,至少需要5位,所以假设就是五位,那么剩下的3条用来扩展操作码,每个地址是六位,所以会扩展出来3×64条192条指令,完全满足二地址指令107条的要求,所以需要的位数为5+6+6+6=23位,由于按照字节编址,所以位数应该是8的倍数,所以是24位,A项正确。扩展操作码关键在于理解好扩展,剩下的数用于扩展,扩展出的操作码为剩下的数乘以地址数,利用好这个关系去列等式即可。
在这里插入图片描述
这道题也是利用扩展来求指令,250条二地址指令,所以需要分配8位,8位会剩下256-250=6条用来扩展,所以单地址指令的条数为6×4K等于24K条。
在这里插入图片描述
对于操作码固定的指令,条数一共就那些,就是一个单纯的减法,第一问地址码长度为6位而且最高到二地址指令,所以留给操作码的位数只剩下4位,所以最多有16条指令,减去零地址指令和一地址指令剩下的就是二地址指令最多的数目,即16-M-N条。这里容易搞混,这个指令的结构划分完之后,最高的四位是对应的操作码,当表示零地址指令时,后面的12位都是地址,但地址一位也没有,剩下没用上的相当于浪费,同理一地址指令只用到6位,剩下的浪费,二地址指令时剩下的12位都用上而且刚刚好满足位数限制。
采用扩展操作码且无零地址指令一地址指令数目限制的情况下,最多是15条,因为需要留下至少一个数去给剩下的地址扩展。
第三问就是要综合利用扩展了。二地址指令有P条,所以剩下的条数为16-P,这些条数扩展得到一地址指令,如果设一地址指令有X条,那么剩下的一地址指令为(16-P)×64-X,再用这些条进行扩展得到的是零地址指令Q,从而可以得到等式:[(16-P)×64-X]×64=Q,可以将X写出来,这个X表示的就是最多的条数。
在这里插入图片描述
这道题考察的就是转移指令过程中的地址变化。指令是两个字节,而且题目明确说了每读取一个字节PC就加一,所以取完指令后PC加二变为2002H,再加上相对位移量字段上的值,变为2008H,所以选择C。
在这里插入图片描述
假设两个无符号整数A和B,bgt指令会将A和B进行比较,也就是将A和B相减。若A>B,则A-B肯定无进位/借位,也不为0,因此 CF 和 ZF 均为 0,选 C。其余选项中用到了符号标志 SF 和溢出标志 OF,显然应当排除。
在这里插入图片描述
16个通用寄存器,对其编号需要4位二进制。32位的指令中,8位用于表示操作码,4位用于源操作数的寄存器直接寻址,目的操作数采用的是基址寻址,需要制定一个寄存器,所以也需要4位,所以剩下的留给偏移量的位数只剩下了32-8-4-4=16位,而16位的补码表示范围是-32768~32767,故A正确。
在这里插入图片描述
根据题意,当读取完转移指令后,PC的值应该加三变成243,再变到290的时候偏移量为47,将47转换为二字节二进制为0000 0000 0010 1111 ,即十六进制的002FH,由于低字节作为字地址,所以2FH为第二字节,00H为第三字节,第一个空选D。同理,240执行完PC变为243,跳转到200偏移量为-43,即1111 1111 1101 0101,转换为十六进制为FFD5H,所以存放在计算机内第二字节为D5H,第三字节为FFH,故第二个空选择C。
在这里插入图片描述
操作数的机器数为1234FF00H,即指令所在的位置。基址寻址中,实际地址等于形式地址加上基址寄存器内的地址,而基址寄存器内为无符号数。偏移量的补码形式为1111 1111 0001 0010,对应的原码为-00EEH,所以实际地址为F0000000H-00EEH=EFFFFF12H,计算机采用大端方式编址,所以低位字节存放在字的高地址处,机器数一共占 4 字节,该操作数的LSB所在的地址是 EFFFFF12H+4-1 = EFFF FF15H,所以选 D。

猜你喜欢

转载自blog.csdn.net/weixin_43849505/article/details/108419974