变长操作码,即全部指令的操作码字段的位数不固定,且分散地放在指令字的不同位置上。最常见的变长操作码方法是扩展操作码,操作码的长度随地址码的减少而增加,不同地址数的指令可以具有不同长度的操作码,从而在满足需要的前提下,有效地缩短指令字长。
举个例子:
若指令长度为16位,并且每个地址码占4位,若设置三地址指令,则地址码总共占3*4=12位 ,剩余4位来表示操作码,4位基本操作码若全部用于三地址指令,则有16(2^4)条。但至少须将1111留作扩展操作码之用,即三地址指令为15条
1111 1111留作扩展操作码之用,二地址指令为15条;CPU取得一条指令时,会直接读入16位,CPU根据开头4位是否为全1,判断是三地址指令或二地址指令,若开头4位是1111,后4位不为全1,则为二地址指令
同理,后4位为全1保留下来,作为一地址指令,一地址指令为15条,若前8位全为1,则为一地址指令
最后4位为0000~1111,前面12位全为1,因为已经不需要拓展了,所以零地址指令为16条
当然还有其他扩展操作码设计方法,这里只是其中一种。
所以在设计扩展操作码指令格式时,必须注意以下两点:
(1) 不允许短码是长码的前缀,即短操作码不能与长操作码的前面部分的代码相同。
例如上面例子,二地址指令操作码为前8位,为长码,三地址指令的操作码为前4位,为短码,不允许短码是长码的前缀的含义为:这4位操作码不能为全1
(2)各指令的操作码一定不能重复。通常情况下,对使用频率较高的指令,分配较短的操作码;对使用频率较低的指令,分配较长的操作码,从而尽可能减少指令译码和分析的时间。
再举一例扩展操作码的示例:
设指令字长固定为16位,若需要15条三地址指令:对于三地址指令而言,需要12位作为地址码,只用前4位(16-12=4)表示操作码,0000~1110表示操作码,1111表示扩展操作码:
需要12条二地址指令,则前4位为1111,二地址指令需要8位地址码,所以只能由中间4位表示操作码:0000(0)~1011(11)总共12条。我们会发现,剩余1100,1101,1110,1111没有对应的操作码,这些位都是以“11”开头的,所以如果开头为1111 11则表示超出了二地址指令的范围。
一地址指令只需要保留最后的4位作为地址码。需要62条一地址指令,则可以用剩下的6位,即黑框部分表示不同的一地址指令:000000(0)~111101(61)。同理,最大的能表示一地址指令的数为:1111 1111 1101 xxxx,如果超出了这一范围,即1111 1111 1110 xxxx,前面11位都为“1”,那么就超出了一地址指令的合法范围。
需要32条零地址指令,剩下的5位刚好能表示00000(0)~11111(31)
按照上面的扩展操作码的设计,若CPU访问的指令最前4位不为全1,则说明这是一条三地址指令
若前4位为全1,再判断紧接着后面2位是否为1,若不为全1,则为二地址指令,若为全1,那么会继续检测后面紧跟的5位是否全为1,若不是,则为一地址指令,若是,则为零地址指令。
对扩展操作码而言,若地址长度为n,上一层留出m种状态,下一层可扩展出 m*2^n 种状态
例如,对于三地址指令,需要用前4位表示操作码,表示2^4=16种状态,留出16-15=1种状态作为下一层的扩展。
对于下一层的二地址指令而言,可以用1111+紧接着后4位的信息,表示这是哪一种状态的指令,2^4=16,而上一层留下的扩展状态为1种,所以总共能表示的状态为1*2^4=16种,而只需要12条二地址指令,所以16-12=4种状态会留到下一层
对于下一层的一地址指令而言,就有4*2^4=64种状态,所以会留出64-62=2种状态到下一层
对于零地址指令而言,就有2*2^4=32种状态
对于留出xx种状态的理解:
每留出1种状态给下一层指令,下一层指令就会多出2^n条指令。
一地址指令给零地址指令留了一种状态,那么就是2^6=64种。
定长操作码和扩展操作码的对比:
定长操作码:在指令字的最高位部分分配固定的若干位(定长)表示操作码。
一般n位操作码字段的指令系统最大能够表示条指令。
优:定长操作码对于简化计算机硬件设计,提高指令译码和识别速度很有利;
缺:指令数量增加时会占用更多固定位,留给表示操作数地址的位数受限。
扩展操作码(不定长操作码):全部指令的操作码字段的位数不固定,且分散地放在指令字的不同位置上。最常见的变长操作码方法是扩展操作码,操作码的长度随地址码的减少而增加,不同地址数的指令可以具有不同长度 的操作码,从而在满足需要的前提下,有效地缩短指令字长。
优:在指令字长有限的前提下仍保持比较丰富的指令种类;
缺:增加了指令译码和分析的难度,使控制器的设计复杂化。
例题1:
(1)操作码固定:操作码位数为4位,所以可以有2^4=16条指令
16=一地址+二地址+零地址,所以二地址指令有16-M-N条。
(2)二地址指令至少给一地址指令留1个扩展窗口:所以二地址指令:2^4-1=15条。
(3)二地址指令操作码4位,有2^4种编码,题目说,二地址指令有p条,则留出种编码用于一地址指令的扩展。
所以一地址指令有种编码。
设留出n种用于零地址的扩展,则,则
所以一地址最多有:
y例题2:
设计某指令系统时,假设采用 16 位定长指令字格式,操作码使用扩展编码方式,地址码为6位,包含零地址,一地址和二地址3种格式的指令,若二地址指令有12条,一地址指令有254条,则零地址指令的条数最多为()
A.0 B.2 C.64 D.128
答案:D
先分析一下:
二地址指令占12(2*6=12)位地址空间,4位用来表示操作码,二地址指令有12条,那么剩余16-12=4条操作码扩展给一地址指令。
0000~1011 xxxx xxxx xxxx
一地址指令格式为,:
11xx xxxx xxxx xxxx,其中低6位为地址码,一地址指令有254条,那么一地址指令可表示的范围:
1100 0000 00xx xxxx~1111 1111 01xx xxxx
其中,00 0000 00~11 1111 01表示0~253,总共254条指令。剩余256-254=2条指令扩展给零地址指令。
1111 1111 1xxx xxxx,前9位固定,因为超过1111 1111 01xx xxxx,就是零地址能表示的范围了。剩余位为16-9=7。所以零地址指令的条数最多为2^7=128条。
当然可以直接用刚刚讲的公式:
二地址指令有12条,则剩余16-12=4种操作码给一地址指令,一地址指令有254条,4*2^6-254=2种操作码给零地址指令,所以零地址指令一共有2*2^6=128条。
还可以这么想:
地址码为6位,一条二地址指令会占用2^6条一地址指令的空间,一条一地址指令会占用2^6条零地址指令的空间。若全都是零地址指令,则最多有2^16条,减去一地址指令和二地址指令所占用的零地址指令空间,即2^16-254x2^6-12x2^6x2^6=128。
例题3:
某计算机按字节编址,指令字长固定且只有两种指令格式,其中三地址指令29条、二地址指令107条,每个地址字段为6位,则指令字长少应该是()
A.24位 B.26位 C.28位 D.32位
分析:三地址指令有29条,需要至少5位操作码,最后会剩余:2^5=32 ,32-29=3种操作码扩展给二地址指令,而二地址额外多了6位操作码,所以数量最大达到3*2^6=192条。所以指令字长最少为5+6+12=23位。
又因为计算机按字节编址,需要8的倍数,所以指令字长至少为24位。
答案:Ass