MIPS汇编
数据定义的例子:
跳转(绝对地址)指令:
JAL(Iump-and-Link):调用指令
jal label #$31=PC+8,jump 在$ra=PC+8中保存返回地址并跳转到相应的过程
JR(Jump Register):返回指令
jr Rs #PC=Rs,将控制转移到任意地址 跳转到在寄存器Rs(PC=Rs)中存储的地址所在指令 j label #只能到达2^28个字节的页内指令 目标地址的高4位是当前PC的高4位值
算术及逻辑指令
addu d,s,t d=s+t addiu d,s,j d=s+(signed)j sub d,s,t d=s-t,溢出时自陷 subu d,s,j d=s-j;addiu d,s,-j div d,s,t 有符号32位除法指令,在被零除和溢出条件下发生 异常 divu $zero,s,t no checks,lo=s/t,hi=s%t mult s,t hilo=(signed)s*(signed)t and d,s,t d=s&t and d,s,j (andi d,s,j),d=s&(unsigned)j,仅用于0<=j<65535, 对于更大的数要生成额外的指令 maddu d,s,t 32位整数乘法累加,两个寄存器以全精度相乘并累 加hilo=hilo+((long long)s*(long long)t
break code 调试器用的断点指令。Code值对硬件没有效果,但 是断点异常例程可以通过读取异常原因指令检索到它的值 cache k,addr 对高速缓存进行操作----第四章会详细说明 ehb (执行遇险防护-当你需要保证上面指令的任何协处理器0的 副作用在随后的指令执行之前已经完成的时候所用的指令) ext d,s,shf,sz 从32位寄存器提取位域。Shf是位域在s中的移位到 第0位所需要的位移量,sz是位域包含的位的个数。mask=(2**sz1)<<shf,d=(s&mask)>>shf ssnop (超标量空操作,是个空操作,但是在同一个时钟周期CPU 不得发送其他指令,用于达到时序目地)
存储器访问
lw t,addr t=*((int *)addr),32位加载,64位CPU上符号扩展 lwl t,addr 向左加载一个字,非对齐加载 lwr t,addr 向右加载一个字 lh d,addr 16位加载,符号扩展到整个寄存器,d=*((signed short *)addr) lhu d,addr 16位加载,零扩展到整个寄存器,d=*((unsigned short *)addr) lbu d,addr 8位加载,零扩展到整个寄存器,d=*((unsigned char *)addr) lb d,addr 8位加载,符号扩展到整个寄存器,d=*((signed char *)addr) lwc2 cd ,addr 32位加载到协处理器2寄存器,如果实现了的话, 很少见 lwxc1 fd,t(b) 采用索引(寄存器+寄存器)地址加载32位浮点, 常写为l.s,fd=*((float *(t+b)
teq s,t if(s==t) exception(TRAP),条件自陷指令,如果相应 的条件满足,生成一个TRAP异常 tge s,t if((signed)s>=(signed)t) exception(TRAP) tge s,j if((signed)s>=(signed)j) exception(TRAP) tgeu s,t if((unsigned)s>=(unsigned)t) exception(TRAP) tgeu s,j if((unsigned)s>=(unsigned)j) exception(TRAP) tne s,t if(t!=s)exception(TRAP) tnei s,j if(s!=j)exception(TRAP) tlt s,t if((signed)s<(signed)t)exception(TRAP) tlti s,j if((signed)s<(signed)j)exception(TRAP) tltu s,j if((unsigned)s<(unsigned)j)exception(TRAP) udi9 d,r,s,uc 在为用户自定义指令保留的指令编码空间内构建指 令。这种指令可以采用三个通用寄存器指令,还可以有用于用户 逻辑的5位辅助操作码uc wait(MIPS32指令,进入某种断电状态。通常通过中止执行直到检 测到中断实现。Wait指令应当从空转循环中调用)
MIPS汇编
汇编语言指令格式:
[标签:] 操作符 标签:可选 [操作数] [#注释]
标记内存地址,必须跟冒号 通常在数据和代码段出现
操作符:
定义操作(如add,sub等)
操作数:
指明操作需要的数据 可以是寄存器、内存变量或常数 大多数指令有3个操作数
L1: addiu $t0,$t0,1
MIPS汇编程序框架
.data伪指令
定义程序的数据段,程序的变量需要在该伪指令 下定义,汇编程序会分配和初始化变量的存储空间
.text伪指令
定义程序的代码段
.global伪指令
声明一个符号位全局的,全局符号可以被其他的 文件引用,用该伪指令声明一个程序的main过程
寻址
直接寻址
la $t0,var1 把var1在主存中的地址拷贝到寄存器t0。var1可以是标签
溢出(有符号数)
两个正数相加,如果结果为负数,就产生了溢出。 两个负数相加,如果结果为正数,就产生了溢出。 换个角度来说: 正数 - 负数 = 负数,就产生了溢出。 负数 - 正数 = 正数,就产生了溢出。
无符号数会出错的地方: 1、两个数相加超出了数所能表示的大小,产生进位 2、小整数减大整数,会借位
地址
间接寻址
lw $t2,($t0) 把t0存放的地址处的字拷贝到t2中 sw $t2,($t0) 把t2中的字存储到t0中地址所指向的主存位置
基址寻址
lw $t2,4($t0) 把t0中地址加4所得的地址所对应的主存中的字载入寄存 器t2中,4为偏移量
数据定义
[名字:] 伪指令 初始值[,初始值]….
对CP0的主要操作有以下的指令: mfhi/mflo rt (Move From Hi/Lo)将CP0的hi/lo寄存器内容传 输到rt通用寄存器中; mthi/mtlo rt 将rt通用寄存器内容传输到CP0的hi/lo寄存器中; 当MIPS体系结构演进到MIPS IV的64位架构后,新增了两条指令 dmfc0和dmtc0,向CP0的寄存器中读/写一个64bit的数据 mtc0 t,cd 把32位数据从通用寄存器传到协处理器寄存器cd。 mtc0访问CPU控制寄存器,mtc1把整数单元数据放到浮点寄存器, mtc2是CPU采用协处理器2指令的时候用。如果协处理器寄存器是 64位宽度,数据加载进低位,但是高32位的状态没有定义 mfc0 t,cs 把32位数据从协处理器cs传送到通用寄存器t,如 果cs是64位宽度,则传送的是低32位,CPU控制寄存器 /p-141124298.html (MIPS指令与汇编)
sw t,addr sb t,addr sh t,addr swc1 ft,addr swc2 ft,addr sdc1 ft,addr sdc2 cs,addr
*((int *)addr)=t,存储一个字 *((char*)addr)=t *((short*)addr)=t 存储单精度浮点数到内存 存储协处理器2寄存器的32位数据 存储双精度寄存器到存储器,常写成s.d 存储64位协处理器2寄存器到存储器
li d,j 将常数j的值放入到寄存器d中 lui t,u (Load Upper Immediat)上位加载立即数(常数u符号扩展到 64位寄存器),t=u<<16 ldc1 d,addr 64位加载协处理器1(浮点)寄存器,常写成l.d ldc2 d,addr 64位加载协处理器2寄存器,如果采用了协处理器2 并且宽度为64位的话
ll(load linked)和sc(store conditional)组成原子操作:
ll d,off(b) …… sc t,off(b) ll从内存读取一个字,以实现接下来的RMW操作,sc向内 存中写入一个字,以完成前面的RMW操作。“ll d,off(b)”指令执 行后,处理器会记住ll操作,“sc t,off(b)”会检查上次ll指令执行 后的RMW操作是否是原子操作(不存在其他对这个地址的操 作),若是,t的值会被更新到内存中,同时t的值变为1,表示操 作成功;若不是,t的值不会被更新到内存,同时t的值变为0,表 示操作失败。
move d,s d=s movt d,s,$fccN if($fcc(N) )d=s($fccN或fcc(N)是FCSR寄存器 中的浮点条件位之一) movf d,s,t if(t)d=s movz d,s,t if(!t)d=s movn d,s,t if(t<0)d=s negu d,s d=-s,没有溢出 pref hint,addr;pref hint,t(b),针对访存进行优化的预取指令。事 先知道可能需要的数据的程序可以进行安排,让所需数据提前进 入高速缓存而不产生副作用,具体实现可以把.8节) syscall B exception(SYSCALL,B),产生一个“系统调用”异常。
or d,s,t d=s | t ori d,s,j d=s|(unsigned)j,跟一个常数执行“或”操作OR sllv d,t,s d=t<<(s%32) (shift left logic by variable) sll d,s,shf d=s<<shf;sll d,t,s,d=t<<(s%32) sra d,s,shf d=(signed)s>>shf,shift-right arithmetic,算术右移, 最高位填充,适用于有符号数,sra d,s,t,d=(signed)s>>(t%32) srav d,s,t sra d,s,t srl d,s,shf d=(unsigned)s>>shf ,shift-right logical,逻辑右移,类 似C的无符号量的移位 srl d,s,t d=((unsigned)s>>(t%32) srlv d,s,t srl d,s,t slt d,s,t d=((signed)s<(signed)t)?1:0 (set on less than) sltu d,s,t d=((unsigned)s<(unsigned)t)?1:0 slti d,s,j d=((signed)s<(signed)j)?1:0 sltiu d,s,t d=((unsigned)s<(unsigned)j)?1:0