您好,欢迎访问三七文档
MIPS汇编汇编语言指令格式:[标签:]操作符[操作数][#注释]标签:可选标记内存地址,必须跟冒号通常在数据和代码段出现操作符:定义操作(如add,sub等)操作数:指明操作需要的数据可以是寄存器、内存变量或常数大多数指令有3个操作数L1:addiu$t0,$t0,1MIPS汇编程序框架.data伪指令定义程序的数据段,程序的变量需要在该伪指令下定义,汇编程序会分配和初始化变量的存储空间.text伪指令定义程序的代码段.global伪指令声明一个符号位全局的,全局符号可以被其他的文件引用,用该伪指令声明一个程序的main过程寻址直接寻址la$t0,var1把var1在主存中的地址拷贝到寄存器t0。var1可以是标签地址间接寻址lw$t2,($t0)把t0存放的地址处的字拷贝到t2中sw$t2,($t0)把t2中的字存储到t0中地址所指向的主存位置基址寻址lw$t2,4($t0)把t0中地址加4所得的地址所对应的主存中的字载入寄存器t2中,4为偏移量数据定义[名字:]伪指令初始值[,初始值]….数据定义的例子:跳转(绝对地址)指令:JAL(Iump-and-Link):调用指令jallabel#$31=PC+8,jump在$ra=PC+8中保存返回地址并跳转到相应的过程JR(JumpRegister):返回指令jrRs#PC=Rs,将控制转移到任意地址跳转到在寄存器Rs(PC=Rs)中存储的地址所在指令jlabel#只能到达2^28个字节的页内指令目标地址的高4位是当前PC的高4位值JALR(Jump-and-LinkRegister)jalrRd,Rs#Rd=PC+8,PC=Rs在Rd=PC+8中存储返回地址,跳转到寄存器Rs(PC=Rs)中存储的地址所在过程,地址仅在运行时可知分支(PC相对寻址)指令:PC+labelblabelgotolabelbeqs,t,labelif(s==t)gotolabelbeqls,t,labelif(s==t)gotolabel)beq可能分支变体,仅当分支放生时才执行延迟槽指令beqzs,labelif(s==0)gotolabel,可能分支变体beqzlbgezs,labelif(s=0)gotolabelbgtzs,labelif(s0)gotolabelbnes,t,labelif(s!=t)gotolabel,可能分支变体bnelbnezs,labelif(s!=0)gotolabel,可能分支变体bnezlblezs,labelif(s=0)gotolabel),可能分支变体blezlbltzs,labelif(s0)gotolabel),可能分支变体bltzl存储器访问lwt,addrt=*((int*)addr),32位加载,64位CPU上符号扩展lwlt,addr向左加载一个字,非对齐加载lwrt,addr向右加载一个字lhd,addr16位加载,符号扩展到整个寄存器,d=*((signedshort*)addr)lhud,addr16位加载,零扩展到整个寄存器,d=*((unsignedshort*)addr)lbud,addr8位加载,零扩展到整个寄存器,d=*((unsignedchar*)addr)lbd,addr8位加载,符号扩展到整个寄存器,d=*((signedchar*)addr)lwc2cd,addr32位加载到协处理器2寄存器,如果实现了的话,很少见lwxc1fd,t(b)采用索引(寄存器+寄存器)地址加载32位浮点,常写为l.s,fd=*((float*(t+b)lid,j将常数j的值放入到寄存器d中luit,u(LoadUpperImmediat)上位加载立即数(常数u符号扩展到64位寄存器),t=u16ldc1d,addr64位加载协处理器1(浮点)寄存器,常写成l.dldc2d,addr64位加载协处理器2寄存器,如果采用了协处理器2并且宽度为64位的话ll(loadlinked)和sc(storeconditional)组成原子操作:lld,off(b)……sct,off(b)ll从内存读取一个字,以实现接下来的RMW操作,sc向内存中写入一个字,以完成前面的RMW操作。“lld,off(b)”指令执行后,处理器会记住ll操作,“sct,off(b)”会检查上次ll指令执行后的RMW操作是否是原子操作(不存在其他对这个地址的操作),若是,t的值会被更新到内存中,同时t的值变为1,表示操作成功;若不是,t的值不会被更新到内存,同时t的值变为0,表示操作失败。swt,addr*((int*)addr)=t,存储一个字sbt,addr*((char*)addr)=tsht,addr*((short*)addr)=tswc1ft,addr存储单精度浮点数到内存swc2ft,addr存储协处理器2寄存器的32位数据sdc1ft,addr存储双精度寄存器到存储器,常写成s.dsdc2cs,addr存储64位协处理器2寄存器到存储器算术及逻辑指令addud,s,td=s+taddiud,s,jd=s+(signed)jsubd,s,td=s-t,溢出时自陷subud,s,jd=s-j;addiud,s,-jdivd,s,t有符号32位除法指令,在被零除和溢出条件下发生异常divu$zero,s,tnochecks,lo=s/t,hi=s%tmults,thilo=(signed)s*(signed)tandd,s,td=s&tandd,s,j(andid,s,j),d=s&(unsigned)j,仅用于0=j65535,对于更大的数要生成额外的指令maddud,s,t32位整数乘法累加,两个寄存器以全精度相乘并累加hilo=hilo+((longlong)s*(longlong)tord,s,td=s|torid,s,jd=s|(unsigned)j,跟一个常数执行“或”操作ORsllvd,t,sd=t(s%32)(shiftleftlogicbyvariable)slld,s,shfd=sshf;slld,t,s,d=t(s%32)srad,s,shfd=(signed)sshf,shift-rightarithmetic,算术右移,最高位填充,适用于有符号数,srad,s,t,d=(signed)s(t%32)sravd,s,tsrad,s,tsrld,s,shfd=(unsigned)sshf,shift-rightlogical,逻辑右移,类似C的无符号量的移位srld,s,td=((unsigned)s(t%32)srlvd,s,tsrld,s,tsltd,s,td=((signed)s(signed)t)?1:0(setonlessthan)sltud,s,td=((unsigned)s(unsigned)t)?1:0sltid,s,jd=((signed)s(signed)j)?1:0sltiud,s,td=((unsigned)s(unsigned)j)?1:0breakcode调试器用的断点指令。Code值对硬件没有效果,但是断点异常例程可以通过读取异常原因指令检索到它的值cachek,addr对高速缓存进行操作----第四章会详细说明ehb(执行遇险防护-当你需要保证上面指令的任何协处理器0的副作用在随后的指令执行之前已经完成的时候所用的指令)extd,s,shf,sz从32位寄存器提取位域。Shf是位域在s中的移位到第0位所需要的位移量,sz是位域包含的位的个数。mask=(2**sz-1)shf,d=(s&mask)shfssnop(超标量空操作,是个空操作,但是在同一个时钟周期CPU不得发送其他指令,用于达到时序目地)moved,sd=smovtd,s,$fccNif($fcc(N))d=s($fccN或fcc(N)是FCSR寄存器中的浮点条件位之一)movfd,s,tif(t)d=smovzd,s,tif(!t)d=smovnd,s,tif(t0)d=snegud,sd=-s,没有溢出prefhint,addr;prefhint,t(b),针对访存进行优化的预取指令。事先知道可能需要的数据的程序可以进行安排,让所需数据提前进入高速缓存而不产生副作用,具体实现可以把pref当成空操作。Hint定义这是哪种类型的预取(详情见8.5.8节)syscallBexception(SYSCALL,B),产生一个“系统调用”异常。teqs,tif(s==t)exception(TRAP),条件自陷指令,如果相应的条件满足,生成一个TRAP异常tges,tif((signed)s=(signed)t)exception(TRAP)tges,jif((signed)s=(signed)j)exception(TRAP)tgeus,tif((unsigned)s=(unsigned)t)exception(TRAP)tgeus,jif((unsigned)s=(unsigned)j)exception(TRAP)tnes,tif(t!=s)exception(TRAP)tneis,jif(s!=j)exception(TRAP)tlts,tif((signed)s(signed)t)exception(TRAP)tltis,jif((signed)s(signed)j)exception(TRAP)tltus,jif((unsigned)s(unsigned)j)exception(TRAP)udi9d,r,s,uc在为用户自定义指令保留的指令编码空间内构建指令。这种指令可以采用三个通用寄存器指令,还可以有用于用户逻辑的5位辅助操作码ucwait(MIPS32指令,进入某种断电状态。通常通过中止执行直到检测到中断实现。Wait指令应当从空转循环中调用)溢出(有符号数)两个正数相加,如果结果为负数,就产生了溢出。两个负数相加,如果结果为正数,就产生了溢出。换个角度来说:正数-负数=负数,就产生了溢出。负数-正数=正数,就产生了溢出。无符号数会出错的地方:1、两个数相加超出了数所能表示的大小,产生进位2、小整数减大整数,会借位对CP0的主要操作有以下的指令:mfhi/mflort(MoveFromHi/Lo)将CP0的hi/lo寄存器内容传输到rt通用寄存器中;mthi/mtlort将rt通用寄存器内容传输到CP0的hi/lo寄存器中;当MIPS体系结构演进到MIPSIV的64位架构后,新增了两条指令dmfc0和dmtc0,向CP0的寄存器中读/写一个64bit的数据mtc0t,cd把32位数据从通用寄存器传到协处理器寄存器cd。mtc0访问CPU控制寄存器,mtc1把整数单元数据放到浮点寄存器,mtc2是CPU采用协处理器2指令的时候用。如果协处理器寄存器是64位宽度,数据加载进低位,但是高32位的状态没有定义mfc0t,cs把32位数据从协处理器cs传送到通用寄存器t,如果cs是64位宽度,则传送的是低32位,CPU控制寄存器(MIPS指令与汇编)
本文标题:MIPS汇编.
链接地址:https://www.777doc.com/doc-2888674 .html