第29章 MIPS的特点

29.1 加载常量

unsigned int f()
{
         return 0x12345678;
};

MIPS和ARM平台的指令都是定长指令。MIPS程序的指令都是32位opcode。在MIPS平台上,我们不可能只使用单条指令就完成对32位常量的赋值操作。所以此类操作至少分两步进行:首先传递32位数据的高16位,然后再通过ORI操作向寄存器传递立即数的低16位。

指令清单29.1 GCC 4.4.5 -O3 (assembly output)

        li        $2,305397760                         # 0x12340000
        j         $31
        ori       $2,$2,0x5678 ; branch delay slot

IDA能够识别此类组合指令。为了方便阅读,它对后面的ORi指令进行了处理:用伪指令LI替换了Ori指令,而且用完整的32位值替换了值的低16位。

指令清单29.2 GCC 4.4.5 -O3 (IDA)

        lui       $v0, 0x1234
        jr        $ra
        li        $v0, 0x12345678 ; branch delay slot

GCC直接生成的汇编输出文件(assembly output)同样使用了LI伪指令。不过GCC的LI实际上是LUI(Load Upper Immediate)指令,把数据的高16位传递给寄存器的高半部分。

29.2 阅读推荐

Dominc Sweetman撰写的《See MIPS Run(第二版)》,2010年印刷。