02计算机组成原理-指令格式
1.指令
指令:由一系列的二进制位(bits)组成的,这些位可以表示不同的操作、操作数地址、跳转目标等。
在 MIPS 架构中,指令的编码是精心设计的,以便 CPU 能够解码并执行相应的操作。每个指令通常都包含操作码(opcode,用于标识指令的类型)、源操作数、目标操作数等部分。
指令有自己的布局格式,叫做指令格式。指令的格式或布局定义了指令在计算机内存中的表示方式
对于指令来说,一条指令最基本的格式就是操作码+地址码
操作码:该指令执行什么操作/具有什么功能,比如说这条指令是用来执行什么操作的,就由操作码来去看。
地址码:被操作信息的地址/数据,对于有些指令会把地址给你,有些指令则是直接给你数据,就如之前提到过的立即数,但我们还是统称位地址码。
对于MIPS架构,每条指令都是32位长,这与MIPS体系结构中数据字的位数相一致。这种固定长度的指令格式简化了指令的解码和执行过程,因为CPU不需要在读取指令时确定指令的长度。
给大家辨析几个有关长度的概念:
字:CPU内部用于整数运算,或者说CPU一次能处理多少位的数据。计算机一次处理的一个数据,一个字由若干个字节组成。
机器字长:字的长度(位数),一般我们简称为字长,等于CPU内部用于整数运算的运算器的位数或者是寄存器的位数。
指令字长:一条指令中所包含的二进制位数,一条指令的长度
存储字长:一个存储单元的二进制的位数。
以上都必须是字节的整数倍,一般来说指令字长是存储字长的整数倍,指令字长=n*存储字长 n>=1
可能会遇到这种题,存储字长为2,指令字长为4,问从内存中取出一条指令,需要访问多少次?-->2次
在计算机科学中,我们通常将这种直接表示为二进制形式的指令称为机器语言或机器码。助记符形式的指令我们称为汇编语言。
2.由汇编语言到机器码
以加法为例:add t0, s1, $s2(从寄存器s2和寄存器s1中,取出这两个寄存器中的数据,相加后把结果放到寄存器t0中)----->机器码是?
该指令包含了一个操作码和三个寄存器。、
关于寄存器,这些寄存器在汇编语言中有特定的名称,如 s0 、 s1 、 t0 、 t1 等。在底层,这些寄存器的名字会被映射成数字,以便硬件能够识别和操作。
例如:
寄存器 s0 \~ s7 在 MIPS 中映射到数字 16 ~ 23。
寄存器 t0 \~ t7 映射到数字 8 ~ 15。
注意这些数字都是无符号数。上面的t0我们就能翻译为1000,同理s1可以翻译为10001,s2可以翻译为10010
这种映射关系使得汇编语言编写的程序能够在底层被正确地转换成机器码,并由硬件执行。当汇编器或编译器处理源代码时,它会将这些寄存器名称转换为相应的数字,以生成正确的机器码。
这种映射关系的设计允许指令集保持简洁和一致,同时使得硬件实现更加高效。
但是我们可以看出1000,10001,10010他们长度都不同,所以这只是个雏形。
2.1R型指令
由于MIPS指令是固定长度的32位格式,操作码和其他字段的位置是固定的。对于ADD指令,其机器码的一般格式如下:
操作码一般由两部分来表示,一部分是低6位一部分是高6位,如图由这低6位和高6位共同看出执行的是加法操作。高6位是0,低6位是32表示是加法
然后每五位就是一个操作数,第一个五位就是第一个源操作数25-21(由于是源操作数是放在寄存器里面的,这五位就存放的是第一个源操作数的寄存器对应的二进制的地址,后同),第二个五位就是第二个源操作数20-16,第三个五位是目标操作数,还剩下五位就是用来存放位移量的,如果有移位指令就会用这五个位置,对加法操作来说没有移位操作那就写0就可以了。

现在我们来填一下这个翻译一下上述指令:

MIPS里面的指令一共分为三类R I J,每一类又属于自己的指令格式,加法指令属于R型的,只要是加法减法这种都是R型指令则前六位一定是0,I型J型前六位就不是,然后R型里面又分很多内容,这个时候看后面6位来具体看是加法还是减法。

总结一下MIPS 完整指令格式:以R型指令为例

各字段名称及含义:

2.2其他类型的指令
但这个R型指令有个缺陷,来看下面这个例子:
取数指令:lw 目标寄存器, 偏移量(基址寄存器)
操作数有三个,两个寄存器和一个立即数。通常,加载指令使用一种称为"基址+偏移"的方式,其中基址是一个寄存器,偏移是一个立即数。
但是R型述指令中,并没有一个字段能够直接容纳一个大点的立即数。他的立即数被限制在了5位,即2^5次方 = 32之内。想想我们定义的数组等这些东西,难道只能定义这么大么?肯定不是的。因此,我们还设定了其他不同的指令格式。
MIPS指令集的完整指令格式包括三种主要类型:R型、I型和J型

其实对于这三类指令,他们的前6位都是OP指令,我们分辨是哪种指令的时候主要就看前面这6位。如果OP是0那就是R型,如果不是就是其他类型的指令。
I型:rs和rt是两个寄存器,立即数能表示最大的数就是216.
1.I型指令有双目运算指令,rs作为第一源操作数,立即数作为第二个源操作数-->放到rt目标寄存器中。比如说:addi s1 s2 100 ,这个的意思就是把存在s1里面存的数据加上100放到s2寄存器里面去
2.lw/ls rs中的数据符号拓展后的立即数(也就是说对于rt和rs里面的数立即数就是一个有符号数了)--->内存地址,也就是说把rs里面的数据和符号拓展后的立即数相加就会得到一个数据,这个数据表示一个内存地址
3.分支指令:rs和rt寄存器里面的数据进行比较,根据比较的结果来判断需不需要去往立即数对应的地址中执行对应的指令,如果不满足条件就不去管了。后续会详讲
J型指令:跳转,后面直接跟了一个立即数,这个立即数就表示的一个地址,J型指令需要做的事就是直接跳转到立即数指向的地址的地方。(立即数可以表示一个数据也可以表示一个地址,但地址仅仅只是一个地址,不要弄混淆了)
3.指令的设计
MIPS指令的长度都固定为32位,即每条指令的长度相同,称为定长指令。
这种设计简化了处理器的设计和指令解码过程,使得硬件在执行指令时无需根据指令的不同长度调整操作,提高了处理效率。尽管不同类型的指令可能在字段分配上有所不同,但每条指令的总长度始终保持一致。
对于指令的设计,我们既希望所有指令长度相同,又希望具有统一的指令格式,两者之间产生了冲突。这就引出了最后一条硬件设计原则:优秀的设计需要适宜的折中方案。
在设计计算机体系结构时,需要在寄存器数量和指令长度之间做出权衡:
一方面,更多的寄存器能够减少对内存的访问频率,提高程序执行效率,因为寄存器比主存更快且访问延迟更短。然而,每增加一个寄存器就需要在指令格式中为该寄存器编号分配额外的位数。
另一方面,保持指令长度不变有利于简化处理器设计和优化流水线处理,同时也有助于减小存储指令所需的存储空间。
因此,在实际应用中,现代指令集架构往往会选择一个折衷方案,比如提供16个或32个通用寄存器,以平衡性能需求与指令编码复杂度之间的关系。像RISC-V等一些现代ISA也通过灵活的扩展机制来解决这一问题,允许根据不同的应用场景和资源需求选择合适的寄存器组大小和其他特性。
4.存储程序思想
当今设计计算机,指令用数字的形式表示。计算机内部采用二进制形式来表示指令和数据。数据既然可以存储在存储器中。那么是不是程序也可以,并且我们可以读写程序?
由此法引出存储程序 (stored- program) 的概念。
这是冯·诺依曼体系结构的核心特征之一,它指出程序和数据在计算机内存中是统一存储和处理的,并且都可以被CPU读取和写入。因此,编辑器程序的源代码可以存放在存储器中,经过编译器编译成机器码后也保存在同一存储器内。当计算机运行时,它可以依次取出指令执行,从而使计算机能够实现动态加载和执行不同程序的能力,极大地提升了计算机系统的灵活性和通用性。
这一革命性的设计使得计算机能够在无需硬件改动的情况下,仅通过改变存储在内存中的程序就可实现不同的计算任务,从而释放了计算机的巨大潜力,为现代信息技术的发展奠定了基础
大概先写这些吧,今天的博客就先写到这,谢谢您的观看。