且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

《逆向工程权威指南》—第2章2.3节MIPS

更新时间:2022-10-12 12:13:49

本节书摘来自异步社区《逆向工程权威指南》一书中的第2章2.3节MIPS,作者【乌克兰】Dennis Yurichev(丹尼斯),更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.3 MIPS
在MIPS指令里,寄存器有两种命名方式。一种是以数字命名($0~$31),另一种则是以伪名称(pseudoname)命名($V0~VA0,依此类推)。在GCC编译器生成的汇编指令中,寄存器都采用数字方式命名。

指令清单2.4 Optimizing GCC 4.4.5(汇编输出)

j       $31
 li      $2,123          # 0x7b

然而IDA则会显示寄存器的伪名称。

指令清单2.5 Optimizing GCC 4.4.5(IDA)

jr      $ra
  li      $v0, 0x7B

根据伪名称和寄存器数字编号的关系可知,存储函数返回值的寄存器都是$2(即$V0)。此处LI指令是英文词组“Load Immediate(加载立即数)”的缩写。

其中,J和JR指令都属于跳转指令,它们把执行流递交给调用者函数,跳转到$31即$RA寄存器中的地址。这个寄存器相当于的ARM平台的LR寄存器。

此外,为什么赋值指令LI和转移指令J/JR的位置反过来了?这属于RISC精简指令集的特性之一——分支(转移)指令延迟槽 (Branch delay slot)的现象。简单地说,不管分支(转移)发生与否,位于分支指令后面的一条指令(在延时槽里的指令),总是被先于分支指令提交。这是RISC精简指令集的一种特例,我们不必在此处深究。总之,转移指令后面的这条赋值指令实际上是在转移指令之前运行的。

MIPS指令集与寄存器名称
习惯上,MIPS领域中的寄存器名称和指令名称都使用小写字母书写。但是为了在排版风格上与其他指令集架构的程序保持一致,本书采用大写字母进行排版。

[1] Calling Convention,又称为函数的调用协定、调用规范。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。