文章目录
指令指令格式操作码地址码指令的长度指令分类定长和不定长指令结构操作数地址码数零地址指令一地址指令二地址指令三地址指令四地址指令定长操作码的指令格式扩展操作码指令格式指令设计要点例例指令
指令,一般指机器指令,只是计算机执行某种操作的命令指令集(指令系统):一台计算机的所有指令的集合,构成该机器的指令系统指令格式
一条指令是机器的一个语句
是一组二进制代码
一条指令通常包含
操作码字段
地址码字段
操作码字段地址码字段(若干操作数的地址码)\begin{array}{|c|c|} \hline 操作码字段&地址码字段(若干操作数的地址码)\\ \hline \end{array} 操作码字段地址码字段(若干操作数的地址码)
操作码
指出指令应该执行什么性质的操作,具有何种功能操作码是 识别指令了解指令功能区分操作数地址内容的组成和使用方法等的关键信息地址码
地址码指出指令的以下方面信息(的若干个)源操作数的地址(可以有若干个)结果的地址下一条指令的地址 地址码给出被操作的信息(指令或者数据)的地址,包括 地址可以是内存地址,比如 参与运算的一个或多个操作数所在地址操作数本身可能是地址(比如跳转指令的跳转目标地址作为操作数Ad(IR)则可能是地址的地址) 运算结果保存地址程序转移地址被调用子程序的入口地址 可以是寄存器地址也可以是IO设备的地址指令的长度
一条指令包含的二进制代码的位数
操作码的长度操作数地址码的长度地址数地址的个数
指令长度和机器字长没有固定关系
通常把指令长度等于机器字长的指令称为单字长指令类似的,有半字长指令和双子长指令(基准长度是机器字长)
指令分类
定长和不定长指令结构
定长指令字结构 如果指令系统的所有指令长度都是相等的,则称该指令集为定长指令字结构特点是: 执行速度快控制简单 变长指令字结构 指令集内的指令的长度随指令的功能而有所差异主存一般是按照字节编址,所以指令字长为字节的整数倍操作数地址码数
指令中的操作数地址码的数目的不同,分为Note♣\clubsuit♣:指令字所包含的操作数地址码数不代表指令的操作数数量 主要是某些指令具有隐含的操作数零地址指令
零地址:
OP\begin{array}{|c|} \hline OP\\ \hline \end{array} OP
只给出操作码OP,没有显示地址
不需要操作数的指令 空操作指令停机指令关中断指令 需要操作数的运算类指令 仅用在堆栈计算机中通常参与运算的两个操作数隐含的从栈顶和次栈顶弹出,送到运算器进行运算在将结果隐含的压入堆栈
一地址指令
OPA1\begin{array}{|c|c|} \hline OP & A_1\\ \hline \end{array} OPA1
这种指令也是有两种的形态(根据操作码来区分)
只有目的地址的单操作数指令
按照A1A_1A1读取操作数
进行OP操作结果保存回原地址(A1A_1A1)
OP(A1)→A1OP(A_1)\to{A_1}OP(A1)→A1
例如:
加1减1求反求补
隐含约定目的地址的双操作数指令
指令(操作数)地址码A1A_1A1读取源操作数指令可以隐含约定另一个操作数有ACC(累加寄存器)提供运算结果放回ACC中(ACC)→OP(A1)→ACC(ACC)\to{OP(A_1)}\to{ACC}(ACC)→OP(A1)→ACC假设: 指令字长32bit操作码占8bit操作数地址码占24bit指令的操作数的直接寻址范围为224=16M2^{24}=16M224=16M
二地址指令
OPA1A2\begin{array}{|c|c|c|} \hline OP&A_1&A_2\\ \hline \end{array} OPA1A2
指令含义:(A1)OP(A2)→A1(A_1)OP(A_2)\to{A_1}(A1)OP(A2)→A1
对于常用的算数逻辑运算指令,往往要求2个操作数,需要分别给出目的操作数和源操作数的地址
其中目的操作数地址还复用作保存本次运算结果
假设OP占8位,A1,A2A_1,A_2A1,A2都各占12位,那么操作数直接寻址范围为212=4K2^{12}=4K212=4K
三地址指令
OPA1A2A3\begin{array}{|c|c|c|c|} \hline OP&A_1&A_2&A_3\\ \hline \end{array} OPA1A2A3
指令含义(A1)OP(A2)→A3(A_1)OP(A_2)\to{A_3}(A1)OP(A2)→A3
如果指令字长32bit,操作码,以及三个地址码都是8bit,指令操作数的直接寻址范围为28=2562^8=25628=256
如果地址字段都是主存地址,则完成一条三地址指令需要4次访问存储器(1次是取指令,2次用来取操作数,1次保存结果,它们的先后顺序是严格的)
四地址指令
OPA1A2A3A4\begin{array}{|c|c|c|c|c|} \hline OP&A_1&A_2&A_3&A_4\\ \hline \end{array} OPA1A2A3A4
(A1)OP(A2)→A3,A4=Next(A_1)OP(A_2)\to{A_3},A_4=Next(A1)OP(A2)→A3,A4=Next Next:下一条将要执行的指令的地址
如果指令字长为32位,操作码OP占8bit,44个地址各占6bit
操作数的直接寻址范围26=642^6=6426=64
定长操作码的指令格式
区分两条指令是不同的,关键是指令的操作码是不同的
这可以体现在操作码二进制串 长度各位是否相等(前缀) 容易联想到haffman编码方法
在指令字的最高位部分分配固定的若干位表示操作码
一般n位操作码的指令系统能够表示2n2^n2n条指令
定长操作码对于简化计算机硬件设计,提高指令译码的速度有利
当计算机字长为32位或者更长,这是常规用法
扩展操作码指令格式
为了在指令字长有限的前提下,仍然保持较多的指令种类,采取可变长度的操作码
指令系统的所有指令的操作码位数不固定
分散地存放在指令字的不同位置上
这增加了译码和分析的难度使得控制器的设计复杂化
最常见的操作码是扩展操作码
使得操作码的长度随地址码的减少而增加不同地址数的指令可以具有不同长度的操作码可以有效缩短指令字长
指令设计要点
不允许短码是长码的前缀
即短操作码不可以是长操作码的前缀
不同指令的操作码不相同
拥有较短的操作码的指令可以执行指令的复杂度不见得一定比较长操作码的指令来的简单(取决于计算机怎么设计的)
譬如,8位操作码的指令和12位操作码的指令之间的区分:
12位操作码的指令的操作码的前8位不可以和8位操作码的指令的操作码有重复应该能够做到,cpu要取具有8位操作码指令的时候,仅仅根据指令的前八位操作码,就可以认出该指令是不是8位操作码指令(而不是4位操作码指令或者12位操作码指令) (从上例途中的安排方式)我们也可以看出,从(0~3)位操作码我们可以排除4位操作码的指令;从(4~7)位操作码我们可以排除具有超过8位操作码的指令
另外,对于长操作码的指令的分配会减少短操作码指令的(数目)
通常,将使用频率较高的指令分配较短的操作码,对使用频率较低的指令分配较长的操作码
有利于减少指令译码和分析的时间
例
假设有指令字长为16位
采用变长操作码指令编制指令
给出一个中可能的划分方案(要求每个操作数地址码占4位)
3地址指令和x地址指令的数量:
OP;A1A2A3OP;A_1A_2A_3OP;A1A2A3OP占4位,3个(操作数)地址码字段各占4位4位二进制数可以组合出16中情况(b0⋯b3b_0\cdots{b_3}b0⋯b3)但是为了通过扩展指令码方式扩展指令码的种类数,不能够将16中码都用作三地址指令否则会造成无法区分3地址指令和x地址指令(KaTeX parse error: Undefined control sequence: \set at position 5: x\in\̲s̲e̲t̲{0,1,2}) 比如某条二地址指令OP占了8bit(记为b0b1⋯b7b_0b_1\cdots{b_7}b0b1⋯b7)b0⋯b3b_0\cdots{b_3}b0⋯b3这部分会和3地址指令中的某一条的操作码重合在机器读取到b0⋯b3b_0\cdots{b_3}b0⋯b3会无法区分到地是二地址还是三地址因此不能够将所有的b0⋯b3b_0\cdots{b_3}b0⋯b3都用于三地址指令至少需要保留其中的一个(或者更多)为了便于描述,我们假设保留下来的4位二进制码为 c0⋯c3c_0\cdots{c_3}c0⋯c3这样,当机器读取了某条指令的前4位就知道,该指令是不是一个三地址指令如果判断出来该指令不是三地址指令,继续测试是否为二地址指令类似的原因,如果要编址1地址指令,那么用于2地址指令的操作码也需要保留一个或者多个用于扩展操作码之用编制2地址指令的操作码时,所保留8bit记为d0⋯d7d_0\cdots{d_7}d0⋯d7
特别的,0地址指令不需要预留扩展码
因为0地址指令的所有位都是操作码的一部分,操作码无法继续扩展(位数)
那么有可以这一年分配:
15条三地址指令(OP:4) 0000∼11100000\sim{1110}0000∼1110 15条二地址指令(OP:8) 11110000∼111111101111\ 0000\sim{1111\ 1110}11110000∼11111110即,前4bit都是三地址预留下来的1111(没有被占用)有所不同的在于第5$\sim$8位这4位 15条一地址指令(OP:12) 111111110000∼1111111111101111\ 1111\ 0000\sim{1111\ 1111\ 1110}111111110000∼111111111110前8bit都是2地址指令预留下来的1111 1111有所不同的是9$\sim$12位 16条0地址指令(OP:16)(所有为都别操作码占有,无需再预留) 1111 1111 1111 0000$\sim$1111 1111 1111 1111
处理上述的分配方案,还有其他的方案,
不同的方案可以产生的总的指令条数不同如果3地址指令减少一条,那么二地址指令条数就可以增加一倍
从操作码的长度角度来看,如果
假设减少一条操作码长度为x的指令则可以多出多少条长操作码的指令?
再举一种可行的分配方案
15条三地址指令 0H∼EH0H\sim{EH}0H∼EH 12条2地址指令 F0H∼FBHF0H\sim{FBH}F0H∼FBH 63条1地址指令 KaTeX parse error: Undefined control sequence: \set at position 20: …\sim{FxF}H,x\in\̲s̲e̲t̲{C,D,E}FF0H∼FFEHFF0H\sim{FFEH}FF0H∼FFEH因此共有3×24+15=48+15=64因此共有3\times{2^4}+15=48+15=64因此共有3×24+15=48+15=64不过也可以废弃掉某些范围内的操作码,比如只采用 FE0H∼FFEHFE0H\sim{FFEH}FE0H∼FFEH则只有16+15=31条一地址指令 1条0地址指令 FFF0H∼FFFFHFFF0H\sim{FFFFH}FFF0H∼FFFFH
例
假设指令字长为16位
每个操作数的地址码为k=6位
根据地址码数,指令有三种格式
0地址1地址2地址
列表分析:
x地址指令表示指令字中地址码字段包含了几个操作数地址码 x不一定表示指令的操作数个数(因为某些指令的操作数是隐含的,不体现操作码字段中🎈)为了便于描述,将体现在指令的地址码字段中的操作数地址码称为显式操作数地址码此类问题我们不关心指令涉及到的操作数的个数只需要关心地址码字段的划分段数(显式操作数地址码)即可
规律分析
从表格中可以看出,如果x地址指令每预留一种编码给(x-1)地址指令,那么就会(最多)增加2k=262^k=2^62k=26条(x-1)地址指令如果考虑预留给x-2地址指令,那么还要减去预留数量
此外,还可以从操作码位数的角度列表
((24−X)×26−M)×26=Y((2^4-X)\times2^6-M)\times2^6=Y((24−X)×26−M)×26=Y
问
如果操作码位数固定(所有指令的操作码位数一致)
一地址指令有P条二地址指令有Q条那么有多少条0地址指令?解: 由于采用固定操作码,应该考虑具有最长操作数地址码长度的情况为基准以保证确定下来的操作码位数是正常的操作码位数为16-6*2=4bit那么指令最多有24=16条2^4=16条24=16条0地址指令最多有16−P−Q16-P-Q16−P−Q条
如果采用变长操作码编制指令,同时
2地址指令有X种
0地址指令有Y种
问一地址指令最多有几种?
解:
设一地址指令最多有M种
2地址指令预留给1地址指令的编码数量R1=24−XR_1=2^4-XR1=24−X
1地址指令数量的最大值M1=R1×26M_1=R_1\times{2^6}M1=R1×26
1地址指令预留给0地址指令的编码数量R2=M1−MR_2=M_1-MR2=M1−M
0地址指令的最大数量M0=R2×26M_0=R_2\times{2^6}M0=R2×26
现在,有告诉你已知0地址指令的数量是Y
则
Y⩽M0=R2×26=(M1−M)×26=(R1×26−M)×26=((24−X)×26−M)×26Y\leqslant{M_0=R_2\times2^{6}=(M_1-M)\times{2^6}} \\=(R_1\times2^6-M)\times{2^6} \\=((2^4-X)\times{2^6}-M)\times{2^6} Y⩽M0=R2×26=(M1−M)×26=(R1×26−M)×26=((24−X)×26−M)×26
从而M⩽26(24−X)−2−6YM\leqslant{2^6(2^4-X)}-2^{-6}YM⩽26(24−X)−2−6Y
一地址指令最多有: 26(24−X)−2−6Y{2^6(2^4-X)}-2^{-6}Y26(24−X)−2−6Y