在mc中存储器有限制实现的存储单元要么体积大要么速度慢。
而且访存速度随着物理地址的增长而线性的提高。
所以提高数据编码密度而降低访存压力是一个非常重要的设计问题。
一般来说一个指令集的一条机械指令可以长这样
【指令名】【对象/立即数】
(先只考虑单地址指令)
比如8bits的指令,可以把前4bits划分为指令名,后4bits划分为对象/立即数。
也就是对指令结构进行定义。
格式A:【指令名4bits】【对象/立即数4bits】
如果某个指令集所有指令固定这种格式。
那么这个指令集最多容下16条指令,并且每条指令可以传入4bits的参数作为对象指针或者立即数。
可是16条指令太少了,况且很多种指令不需要传入参数。
于是就有了新的指令格式
格式B: 【指令名8bits】
如果要混用多种指令格式,就必须区分不同的指令格式。一种最纸张的办法就是专门用一条指令的前nbits去表识这个指令的格式。比如第位为0则是第一种格式,为1是第二种格式。
采用这种方法划分后。两种格式便分别只剩下7bits的编码空间了。
如果用这种办法划分上面那两种格式,我们可以在编码空间中设计出这么多的指令:
格式A的指令7条,格式B的指令2^7条。
显然格式B的指令太多而格式A指令太少。
如果格式A的指令位不够用,可以采用折中的办法,比如改变检测指令格式的方法:
现在把指令格式判别的条件改为:
如果高4bits都是1,则该指令格式为B,否则为A。
这样编码后,可以定义15个A格式指令与16个B格式指令。显然更加平衡一些了,
类似的,还可以通过更改为其他判定条件平衡格式A指令与格式B指令的可编码数量。
比如说条件改为前3bits为1则格式为B之类的。。。
这是通过指令结构上的优化,或者支持多种指令格式,而实现的编码压缩/优化
除此之外,还可以将某些绝对不会用到的参数指令,赋予新的意义。
比如某个指令集支持指令
{or a,b}其中a,b是寄存器对象,假定寄存器有ax,bx,cx,dx四个。
这条指令的功能是“ a <- a | b”也就是a,b进行或运算然后写回a。
不难看出。
or ax,ax
or bx,bx
or cx,cx
or dx,dx
这四条指令的含义都是nop。但是nop只需要一个就够了。
所以不妨将其中的一个挑选出来保留作为nop等价指令,比如or ax,ax
而其他的就赋予新的意义,比如将or bx,bx的二进制编码含义重新定义为"not ax"也就是取反ax
这样就可以将这些没有意义的双对象指令重定义为新的功能指令,得以在指令集中插入更更多指令。
同样。对于单操作数的质量,如果用双操作数指令格式编码也是一种浪费,大可多提供一种指令格式专门编码单操作数指令。
实际上的设计可以自由的多,尤其是对8bits的单指令指令集。8bits只存在16*16种不同的情况。
可以画出一个16*16的网格。然后在每个格子上填写预期的指令,注意每个格子中的指令如果涉及参数,都必须确定它的参数是什么,也就是说,要穷举它所有可能的参数。这时候当然也可以发现一些无用的传入参数。这时候便可赋予新的含义。这样的做法就跟下面的图一样。
当然下面那张图里还是折中的将立即数获得指令imm定义成了双地址指令。
这是因为立即数指令如果使用双地址格式反而更好(单指令格式会浪费很多的编码位置,甚至还必须增加完整立即数读取所需的指令数)


而且访存速度随着物理地址的增长而线性的提高。
所以提高数据编码密度而降低访存压力是一个非常重要的设计问题。
一般来说一个指令集的一条机械指令可以长这样
【指令名】【对象/立即数】
(先只考虑单地址指令)
比如8bits的指令,可以把前4bits划分为指令名,后4bits划分为对象/立即数。
也就是对指令结构进行定义。
格式A:【指令名4bits】【对象/立即数4bits】
如果某个指令集所有指令固定这种格式。
那么这个指令集最多容下16条指令,并且每条指令可以传入4bits的参数作为对象指针或者立即数。
可是16条指令太少了,况且很多种指令不需要传入参数。
于是就有了新的指令格式
格式B: 【指令名8bits】
如果要混用多种指令格式,就必须区分不同的指令格式。一种最纸张的办法就是专门用一条指令的前nbits去表识这个指令的格式。比如第位为0则是第一种格式,为1是第二种格式。
采用这种方法划分后。两种格式便分别只剩下7bits的编码空间了。
如果用这种办法划分上面那两种格式,我们可以在编码空间中设计出这么多的指令:
格式A的指令7条,格式B的指令2^7条。
显然格式B的指令太多而格式A指令太少。
如果格式A的指令位不够用,可以采用折中的办法,比如改变检测指令格式的方法:
现在把指令格式判别的条件改为:
如果高4bits都是1,则该指令格式为B,否则为A。
这样编码后,可以定义15个A格式指令与16个B格式指令。显然更加平衡一些了,
类似的,还可以通过更改为其他判定条件平衡格式A指令与格式B指令的可编码数量。
比如说条件改为前3bits为1则格式为B之类的。。。
这是通过指令结构上的优化,或者支持多种指令格式,而实现的编码压缩/优化
除此之外,还可以将某些绝对不会用到的参数指令,赋予新的意义。
比如某个指令集支持指令
{or a,b}其中a,b是寄存器对象,假定寄存器有ax,bx,cx,dx四个。
这条指令的功能是“ a <- a | b”也就是a,b进行或运算然后写回a。
不难看出。
or ax,ax
or bx,bx
or cx,cx
or dx,dx
这四条指令的含义都是nop。但是nop只需要一个就够了。
所以不妨将其中的一个挑选出来保留作为nop等价指令,比如or ax,ax
而其他的就赋予新的意义,比如将or bx,bx的二进制编码含义重新定义为"not ax"也就是取反ax
这样就可以将这些没有意义的双对象指令重定义为新的功能指令,得以在指令集中插入更更多指令。
同样。对于单操作数的质量,如果用双操作数指令格式编码也是一种浪费,大可多提供一种指令格式专门编码单操作数指令。
实际上的设计可以自由的多,尤其是对8bits的单指令指令集。8bits只存在16*16种不同的情况。
可以画出一个16*16的网格。然后在每个格子上填写预期的指令,注意每个格子中的指令如果涉及参数,都必须确定它的参数是什么,也就是说,要穷举它所有可能的参数。这时候当然也可以发现一些无用的传入参数。这时候便可赋予新的含义。这样的做法就跟下面的图一样。
当然下面那张图里还是折中的将立即数获得指令imm定义成了双地址指令。
这是因为立即数指令如果使用双地址格式反而更好(单指令格式会浪费很多的编码位置,甚至还必须增加完整立即数读取所需的指令数)















