赞
踩
1.为了简化处理器的设计,MIPS处理器采用了固定结构的汇编指令:每个指令由4个部分组成:1个操作符+3个操作数
指令格式:指令代码 操作数1,操作数2,操作数3
2.在汇编指令中,寄存器没有数据类型,由运算符确定将寄存器的内容当作什么数据来处理
3.MIPS既提供了检测溢出的加(add)、减(sub)指令,也停供了不检测溢出的加(addu)、减(subu)指令
以适用不同高级语言的需求
1.为了是使硬件设计更简单,MIPS处理器的汇编语言中,算术运算指令的操作数只能是寄存器。
2.在MIPS计算机中设计了32个32位的通用寄存器来作为汇编指令的操作数,分别编号位0-31.
既可以通过编号也可以通过寄存器名来访问指定的寄存器
3.MIPS定义了一个特殊的处理器$S0,该寄存器的值永远都是0
4.由于计算机运算速度很快,对于需要延时的程序。可以有一条不做任何处理,仅延时一个周期的指令noop,
该指令没有任何操作数:add $0,$0,$0
1、立即数在代码中可立即获得,不必先放到寄存器中再从寄存器中取出
2、可以通过加负常数来实现减正常数,因此在MIPS中没有立即数减法指令
MIPS算术指令不能直接操作内存,仅能直接操作寄存器,因此要操作内存中数据必须先将其从内存中装入到存储器中,
然后再对寄存器中的数据进行运算
1、内存地址为寄存器(包含指向内存的指针)和数值偏移量(以字节为单位)之和
2、从内存取出数据的指令语法格式:
其中:1表示指令名字;2表示接受内存传入值的寄存器名;3表示数值偏移量(单位:字节)4是寄存器名,该寄存器中存储的是内存地址,其中括号表示地址
例如: lw $t0,12($s0)
表示:取出寄存器$s0中的指针与立即数12相加,将结果作为内存地址,从内存中取值,把趣得的值放入到$t0中
1、把寄存器的值存储到内存中:
例如:sw $t0,12($t0)
表示:取出$s0中的指针,加上12字节,得到内存地址的值,然后把寄存器$t0中的值存储到该内存地址中
2、寄存器可以保存任意32位数值,可以是有符号整数、无符号整数、指针等,但不能混用
1、在现代计算机中,既要访问字节,也要访问字,主要采用的是字节寻址,其相邻的两个32位(4字节)字地址相差4个字节
表示各个字的地址方式为:
memory[0],memory[4],memory[8]....
2、相邻字之间的地址相差4个字节,而不是一个字节,不能简单加1
3、对于lw、sw,基地址和偏移地址之和必须是4的倍数,即需要字对齐,如果字没有对齐,则读数据操作需要两次才能完成
1、除了传送字数据的指令lw,sw外,MIPS还有字节传送指令:lb(load byte)和sb(store byte),其格式于lw,sw相同
例如:lb $s0,3,($s1)表示:把位于($s1)+3内存地址的内容复制到寄存器s0中,但寄存器有32位,传送的数据只有八位,放在低字节中
2、对于无符号数,指令lbu(load byte unsigned)用来装入字节,并对高位数据进行零拓展。既装入8位数据到寄存器的低字节中,其余24位补0.
其含义是:register1于register2相等,则跳转到标号L1处的语句,否者不执行;
对应于:if(register1==register2) goto L1
对应于:if(register1!=register2) goto L1
该指令又称跳转指令,即不需要满足任何条件而之间跳转到指定的标号处
1、两个“逻辑”指令
①逻辑左移指令sll(shift left logic)
例如:sll $s1,$s2,2 #s1=s2<<2表示:将寄存器$s2的值左移2位,并将结果存放到$s1中,右边空出来的位中补0,和C语言中的<<运算符等价
②逻辑右移指令srl(shift right logic)
2、循环
以下为一段c语言循环程序:
- do{
- g=g+A[i];
- i=i+j;
- }while(i!=h);
要把它翻译成MIPS程序,首先要重写以上程序为条件语句的形式
- Loop:
- g=g+A[i];
- i=i+j;
- if(i!=h)
- goto Loop;
然后使用以下映射关系:
g->$s1; h->$s2; i->$s3; j->$s4;
则可以把以上语句翻译为以下MIPS代码:
- Loop:
- sll $t1,$s3,2 #$t1=4*i,乘4得字节地址
- add $t1,$t1,$s5 #$t1=A的地址
- lw $t1,0($t1) #$t1=A[i]
- add $s1,$s1,$t1 #g=g+A[i]
- add $s3,$s3,$s4 #i=i+j
- bne $s3,$s2,loop #if (i!=h)goto Loop
1、MIPS设计过程中,通过提供一条指令来实现4种条件分支:slt(set on less than)
其语法为:slt reg1,reg2,reg3
与其对应的C语句是:reg1=(reg2<reg3);
利用slt指令可以实现小于分支,例如C语言中的小于分支语句:
if(g<h)goto Less;
变量映射为:g:$s0,h:$s1
可以翻译为MIPS代码:
- slt $t0,$s0,$s1 #如果g<h,则$t0=1
- bne $t0,$s0,Less #if($t0!=0) goto Less
将bne改成beq即可实现大于等于的判断
- slt $t0,$s0,$s1 #$t0=1 if a<b
- beq $t0,$s0,GreatE #GreatE if(a>=b)
同理也可实现小于和小于等于的判断
2、另外,MIPS也设计了slt的立即数版本slti,用来和立即数比较
例如:
C语句:
if(g>=1) goto Loop
转化成MIPS为:
- slti $t0,$s0,1
- beq $t0,$s0,Loop
3、同样还有针对无符号数的不等式判断指令:stlu,stliu
(寄存器中的数是二进制串,本身不存在有符号或无符号的定义,其含义取决于指令)
例如:$s0=FFFF FFFA $s1=0000 FFFA
当看成无符号数时,$s0>$s1;看作有符号数时,$s0为负数,$s0< $s1
4.在MIPS的指令中,无符号标识u具有不同的含义。对于装入字节lbu,是进行符号扩展;对于addu是不检测溢出,而sltu是进行无符号数比较
C语言:
- switch(k)
- {
- case 0:f=i+j;break;
- case 1:f=g+h;break;
- case 2:f=g-h;break;
- case 3:f=i-j;break;
- }
先改写为if-else语句:
- if(k==0) f=i+j;
- else if(k==1) f=g+h;
- else if(k==2) f=g-h;
- else if(k==3) f=i-j;
使用以下映射:f:$s0; g->$s1; h->$s2; i->$s3; j->$s4; k->$s5
- bne $s5,$0,L1 #branch k!=0
- add $s0,$s3,$s4 #k==0,f=i+j
- j Exit
- L1:
- addi $t0,$s5,-1 #$t0=k-1
- bne $t0,$0,L2 #branch k!=1
- add $s0,$s1,$s2 #k==1,f=g+h
- j Exit
- L2:
- addi $t0,$s5,-1 #$t0=k-2
- bne $t0,$t0,L3 #branch k!=2
- sub $s0,$s1,$s2 #k==2,f=g-h
- j Exit
- L3:
- addi $t0,$s5,-3 #$t0=k-3
- bne $t0,$0,Exit #branch k!=3
- sub $s0,$s3,$s4 #k==3,f=i-j
- Exit:

地址跳转指令jr(jump to register):jr $ra #跳转到寄存器所指定的地址
由于调用过程需要两条指令:一条存储返回值,一条实现跳转
MIPS设计了一个专门的跳转指令jal(jump and link)
例如:
- addi $ra,$zero,0x1010 #存储函数返回地址
-
- j sum #调用函数sum
可以替换为:
jal sum
其执行过程分为两步:
①link:保存下一指令的地址到$ra
②jump:跳转到给定标记处label
1、在MIPS处理器中,所有指令都占4个字节,和数据一样存储在内存中
2、MIPS规定使用通用寄存器$ra来存储返回值地址。
3、约定:(也可以存放在栈中)
函数返回地址:$ra
函数参数:$a0,$a1,$a2,$a3
函数返回值:$v0,$v1
1、MIPS通过通用寄存器$sp作为栈指针来指向栈的最后使用空间。在使用栈时,首先将栈指针下移,然后将信息填充到移出的空间中
2、函数嵌套调用流程:
①申请栈空间,保护主调函数返回地址以及后面可能用到的值到栈
②调用下级函数前,对下级函数形参进行必要的赋值
③使用跳转语句jal调用函数mult
④从栈中恢复值
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。