
mips指令
中国留学生之父-退税申请书
2023年2月23日发(作者:小白兔蜕变史)通过简单例⼦,学习MIPS指令集(⼀)
要控制计算机的硬件⼯作,必须使⽤它的语⾔。MIPS指令集是计算机应⽤中最简单的指令集,弄懂MIPS指令集,可以帮助我们更好的
理解计算机的运⾏原理。
本⽂⼤量参考这本书(提取码为:os0a),如果你看完觉得不过瘾,可以下载原书籍深⼊学习。本⼈⾮科班出⾝,⽂章避免不了存在
错误之处,发现不对的地⽅,还望指出,⼀起进步。
先来看⼏个简单概念,什么是机器语⾔?汇编语⾔?指令?指令集?
机器可以直接识别的语⾔,就是机器语⾔,⼀般是具有⼀定格式的1和0的组合,上图中指令的'⼆进制表⽰⾏'就是机器语⾔。MIPS中指令
都是32位的。
由于101010...这样的机器语⾔,⼈类很难理解和记忆其表⽰的含义,于是就创造了诸如add$s0,$s1,$s2这样的⼈类看起来较为直观的
汇编语⾔,上图中'add⾏'就是汇编语⾔。我们⽤⾼级程序语⾔编写的程序,先经过编译器编译成汇编语⾔,然后再经过汇编器,编译成机器
语⾔。
机器语⾔和汇编语⾔可以认为是指令的⼀体两⾯。三者含义相似,指令是概括的说法。
指令集,顾名思义,就是⼀组指令的集合。按照不同规则设计的指令的集合,就是不同的指令集。
⼀、加减法指令:
例1:将下述C语⾔中两条赋值语句翻译成MIPS指令。
a=b+c;
d=a-e;
解:在编译过程中,编译器负责将寄存器和程序变量⼀⼀对应起来,此处我们假定变量a,b,c,d,e被分别分配到寄存器
$s0,$s1,$s2,$s3,$s4,编译后的汇编代码如下(#后为该⾏汇编代码的注释):
add$s0,$s1,$s2#将变量b($s1)和c($s2)相加,把它们之和存储在a($s0)中
sub$s3,$s0,$s4#⽤变量a($s0)减去e($s4),将它们之差值存储在d($s3)中
针对上述汇编代码,你可能有这样的疑问:
1、为什么要把变量对应到寄存器?
因为MIPS中的算数运算操作只作⽤于寄存器(可以这样理解:CPU中算术逻辑单元只能对寄存器中的数据进⾏直接运算),因此变量必须
要对应到寄存器,才能进⾏运算。
2、为什么是$s0,$s1,$s2,$s3,$s4这⼏个寄存器?
MIPS中有32个寄存器,编号从0到31。寄存器$s0到$s7对应的寄存器号为16到23,这些寄存器主要就是⽤来进⾏算数运算操作的。
例2:将下述C语⾔代码翻译成MIPS指令。
f=(g+h)-(i+j);
解:我们同样假定变量f,g,h,i,j被分别分配到寄存器$s0,$s1,$s2,$s3,$s4,同时,此例中我们还要引⼊两个临时变量t0(⽤来存储
g+h的结果)和t1(⽤来存储i+j的结果),分别被分配到寄存器$t0和$t1,编译后的结果如下:
add$t0,$s1,$s2#将变量g($s1)和h($s2)相加,把它们的和存储在t0($t0)中
add$t1,$s3,$s4#将变量i($s3)和j($s4)相加,把它们的和存储在t1($t1)中
sub$s0,$t0,$t1#⽤变量t0($t0)减去t1($t1),将它们之差值存储在f($s0)中
你可能还会有这样的疑问:上述指令中的$t0和$t1是哪⾥来的,为什么要引⼊这两个寄存器?
答案是:⼀条MIPS指令只能执⾏⼀个运算,所以编译器会将这条稍复杂的C语⾔代码编译成多条汇编语⾔指令。
可以认为是多了⼀个中间环节:
$t0和$t1是MIPS中专门⽤来存储临时数据的寄存器。这样的寄存器也有8个,分别是$t0到$t7,对应MIPS32个寄存器中的8到15号。
⼆、数据传送指令:
例3:a是含有100个字的数组(字可以简单理解为指令集中寄存器的位数,本篇⽂章中,我们默认字是32位,很显然,像数组a这样的数据
结构,含有的数据元素甚⾄超过寄存器的数量,只能存放在存储器中),试编译C语⾔赋值语句:g=h+a[8];
解:我们假设编译器将寄存器$s1、$s2分别分配给变量g、h,同时假设数组a的起始地址存储在寄存器$s3中。编译后结果如下:
lw$t0,32($s3)#将a[8]加载进寄存器$t0中;lw指令是loadword的简写,表⽰将数据从内存加载⾄寄存器中,($s3)表⽰数组a的起始地址,32表⽰偏移量,就是到起
add$s1,$s2,$t0#将变量h($s2)和t0($t0)相加,把它们的和存储在g($t1)中;
例4:a是含有100个字的数组,试编译C语⾔赋值语句:a[12]=h+a[8];
解:我们假设编译器将寄存器$s2分配给h,同时假设数组a的起始地址存储在寄存器$s3中。编译后结果如下:
lw$t0,32($s3)#将a[8]加载进寄存器$t0中;
add$t0,$s2,$t0#将变量h($s2)和t0($t0)相加,把它们的和存储在寄存器$t0中;
sw$t0,48($s3)#将寄存器$t0中的值写⼊数组a[12]中;sw指令是storeword的简称,表⽰将数据从寄存器存储到内存中。($s3)表⽰数组a的起始地址,48表⽰偏移量
最后,摘抄极客时间徐⽂浩⽼师的专栏《深⼊浅出计算机组成原理》中部分内容,扩展下知识范围:
MIPS的指令是⼀个32位的整数,⾼6位叫操作码(Opcode),也就是代表这条指令具体是⼀条什么样的指令,剩下的26位有三种格
式,分别是R、I和J。
R指令是⼀般⽤来做算术和逻辑操作,⾥⾯有读取和写⼊数据的寄存器的地址。如果是逻辑位移操作,后⾯还有位移操作的位移量,⽽最后
的功能码,则是在前⾯的操作码不够的时候,扩展操作码表⽰对应的具体指令的。
I指令,则通常是⽤在数据传输、条件分⽀,以及在运算的时候使⽤的并⾮变量还是常数的时候。这个时候,没有了位移量和操作码,也没
有了第三个寄存器,⽽是把这三部分直接合并成了⼀个地址值或者⼀个常数。
J指令就是⼀个跳转指令,⾼6位之外的26位都是⼀个跳转后的地址。
后续⽂章会陆续介绍其他的指令。
看到本⽂觉得有收获的兄弟,有多余的C币,随便打赏⼏个,给博主以后下载⽂章使⽤。