mips汇编中的.set伪指令

在汇编文件中总共有三种类型的语句:指令,汇编语言指示器/伪指令,宏。指令包括arch定义的基础指令和扩展指令,扩展指令是在基础指令的基础上进行扩展的,使用助记符方式使得对汇编编程人员更加友好,最终经过汇编器之后变成基础的指令组合到机器上运行。而汇编指示器/伪指令指导汇编器如何处理代码,常见的有.text,.data,.global,.ascii,此外还有一些和arch相关指示器:x86中的DB,mips中的:.set。宏和C语言的宏的作用和用法是相同的,常见的宏有:LEAF(x), END(x)。下面主要是记录一下mips中的.set的作用。

在mips中.set xxx是一条伪指令,它指示汇编器如何处理之后的汇编代码,典型的有以下几种:

.set push --> save all settings
.set pop --> restore saved settings
.set reorder/noreorder --> let/don't let assembler reorder instructions
.set at/noat --> let/don't let assembler use the register $at in instruction aliases (li,la, etc.)
.set mipsn --> let assembler use corresponding ISA instructions to translate
  • .set mipsn

n是一个从0到5的数字,或是数字32或64。1到5,32或64使汇编器从源程序中的这一点开始接受相应ISA级别的指令。 .set mipsn 不仅影响允许使用那些指令,还影响到某些宏如何被扩展。
.set mips0保持原本的ISA级别:这个级别是通过命令行选项选择的,或者是配置的默认值。可以通过这个特性在32位汇编模式中使用r4000的指令
.set mips1 下面的指令是R2000/R3000指令,即MIPS I指令集
.set mips2下面的指令是R6000指令,即MIPS II指令集,这个没有产品化的芯片,一般不要使用
.set mips3下面的指令是R4000指令,即MIPS III,第一个支持64位的指令集
.set mips4支持MIPS IV指令集,它是在MIPSIII的基础上增加了一些浮点指令
.set mips5支持MIPS V指令集,在MIPS IV上增加了SIMD指令
另外.set mips32/mips64支持MIPS32/MIPS64指令集

这个牵扯到MIPS的指令集标准历史,1998年MIPS Technologies从SGI公司分离出来之后发布的指令集标准,MIPS32是MIPS II的超集,MIPS64是MIPS IV的超集

  • .set noreorder/reorder

默认汇编器处在reorder的模式下,该模式允许汇编器对指令进行重新排序,以避免流水线堵塞并获得更好的性能,在这种模式下,是不允许在代码中插入 nop指令的。反之,在noreorder模式下,指令的顺序不会被改变也不会对代码进行任何优化。这样做的优点是程序员可以完全控制代码的执行顺序,缺点是必须手工对指令排序,并在分支和加载指令的延迟槽中填上有用的指令或nop指令.比如:

.set noreorder
lw   t0, 0(a0)
nop        #加载指令延迟槽
sub  t0, 1
bne  t0, zero, loop
nop        #分支指令延迟槽
.set reorder
  • .set volatile/novolatile

处在volatile区的所有存取指令都不会被移动位置(特别是存取指令之间的相对位置)。这一点对访问内存映射设备的寄存器非常重要。因为对于外围设备而言,读写的次序十分重要。另外对读状态寄存器也非常重要。因为想得到的状态都是最新的。举例来说,如果下列代码没有使用.set volatile,那么汇编器很有可能会对第二个lw指令移到指令的前面,因为这样可以填充第一条lw指令的延迟槽:

.set volatile
lw   t0, 0(a0)
sw   t0, 0(a1)
lw   t0, 4(a0)
.set novalatile

避免流水线堵塞的操作以及其他各种优化措施不受该设定的影响.

《see mips run》中文版

noat, nomacro, noreorder: 汇编语言控制操作,为程序员提供了一种方式来关闭汇编器做的一些更复杂的工作,这些工作不总是受欢迎的(相应的没有“no”的名字将该特性重新打开)
.set noat 阻止汇编器将汇编代码翻译成二进制序列依赖at/$1寄存器
.set nomacro 阻止汇编器将一条汇编代码翻译成多条指令
.set noreorder 阻止汇编器调整代码序列来将有用的指令放入分支延迟槽。

参考链接:

x86汇编:https://www.tutorialspoint.com/assembly_programming/index.htm
mips汇编:https://chortle.ccsu.edu/AssemblyTutorial/index.html
GNU as汇编:http://web.mit.edu/gnu/doc/html/as_20.html

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页