mips汇编程序中的.set指令使用

.set push --> save all 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 pop --> restore saved settings

.set mipsn。n是一个从0到5的数字,或是数字32或64。1到5,32或64使汇编器从源程序中的这一点开始接受相应ISA级别的指令。 .set mipsn 不仅影响允许使用那些指令,还影响到某些宏如何被扩展。 .set mips0保持原本的ISA级别:这个级别是您通过命令行选项选择的,或者是您的配置的默认值。您可以通过这个特性在32位汇编模式中使用r4000的指令。小心使用这个命令!
命令‘.set mips16’使汇编器进入MIPS 16模式,传统的汇编器不支持这个命令
伪操作 .set mips3 告诉汇编器下面的指令是MIPS IV(64位指令集,兼容32位指令)中的指令。

1..set noreorder/reorder
默认汇编器处在reorder的模式下,该模式允许汇编器对指令进行重新排序,以避免流水线堵塞并获得更好的性能,在这种模式下,是不允许在代码中插入 nop指令的。反之,在noreorder模式下,指令的顺序不会被改变也不会对代码进行任何优化。这样做的优点是程序员可以完全控制代码的执行顺序,缺点是必须手工对指令排序,并在分支和加载指令的延迟槽中填上有用的指令或nop指令.比如:
.set noreorder
lw   t0, 0(a0)
nop        #加载指令延迟槽
sub  t0, 1
bne  t0, zero, loop
nop        #分支指令延迟槽
.set reorder
2. .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》关于.set指令的介绍:

.set directives:
These are used to tell the assembler how to do its work. By default,MIPS assemblers try to ?ll branch and load delay slots automatically by reorder-
ing the instructions around them(but don’tworry—the assembler never moves instructions around in ways that are unsafe; it leaves delay slots
un?lled if it can’t ?nd a safe rearrangement). Most of the time this is helpful, because itmeans you don’t have to worry about ?lling delay slots
as you write your assembly files.
But what if we need to retain precise control over instruction ordering, as in the case of a heavily used library function? This is the purpose of the .set noreorder directive: It tells the assembler to suppress its reordering capabilities until the next time it encounters a corresponding
.set reorder directive.
For the section of code enclosed between this pair of directives, we’re telling the assembler to put the op-codes it generates into the object file in the same order as the instructions are written.
Labels: “1:” is a numeric label, which most assemblers will accept as a local label. You can have as many labels called “1” as you like in a pro-gram; a reference to “1f ” (forward) will get the next one in sequence and “1b” (back) the previous one. That’s very useful.
Instructions: You’ll notice some unexpected sequences, since the .set noreorder exposes the underlying branch delay slots, and leaves us to ensure (for ef?ciency) that load data is never used by the following instruction.
For example, note the use of register t2 in the second half of the unrolled loop. It’s necessary to use a second register because the lbu t2,-1(a0) is in the delay slot of the preceding branch instruction and thereforemust not overwrite t0—if the branch is taken, the code at its target will make use of the value in t0.

 


《see mips run》最后的“mips glossary”里也有提到:

noat, nomacro, noreorder: Assembly language controls, which provide the programmer with a way of disabling some more complicated things the assem-bler does and that are not always welcome (the corresponding names without the “no” switch the features back on again).
.set noat prevents the assembler from translating assembly code into binary sequences relying on the at/$1 register.
.set nomacro prevents the assembler from translating a single assembly statement into more than one instruction.
.set noreorder prevents the assembler fromjuggling the code sequence to move useful instructions into the branch delay slot.

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

阅读更多

没有更多推荐了,返回首页