Comparisons of MIPS disassembly and decompilation
Here are some side-by-side comparisons of disassembly and decompiler for MIPS. Please maximize the window too see both columns simultaneously.
The following examples are displayed on this page:
Simple code
This is a very simple code to decompile and the output is perfect. The only minor obstacle are references through the global offset table but both IDA and the Decompiler handle them well. Please note the difference in the number of lines to read on the left and on the right.
# void __fastcall free_argv(int argc, char **argv)
.globl _Z9free_argviPPc # weak
_Z9free_argviPPc: # CODE XREF: test_expand_argv(void)+264↑p
# test_expand_argv(void)+51C↑p ...
var_10 = -0x10
var_4 = -4
var_s0 = 0
var_s4 = 4
arg_0 = 8
arg_4 = 0xC
# __unwind {
addiu $sp, -0x28
sw $ra, 0x20+var_s4($sp)
sw $fp, 0x20+var_s0($sp)
move $fp, $sp
la $gp, _GLOBAL_OFFSET_TABLE_+0x7FF0
sw $gp, 0x20+var_10($sp)
sw $a0, 0x20+arg_0($fp)
sw $a1, 0x20+arg_4($fp)
lw $v0, 0x20+arg_4($fp)
beqz $v0, loc_17778
nop
sw $zero, 0x20+var_4($fp)
loc_1770C: # CODE XREF: free_argv(int,char **)+80↓j
lw $v1, 0x20+var_4($fp)
lw $v0, 0x20+arg_0($fp)
slt $v0, $v1, $v0
beqz $v0, loc_17760
nop
lw $v0, 0x20+var_4($fp)
sll $v0, 2
lw $v1, 0x20+arg_4($fp)
addu $v0, $v1, $v0
lw $v0, 0($v0)
move $a0, $v0
lw $v0, (qfree_ptr-0x7FF0 - _GLOBAL_OFFSET_TABLE_)($gp)
move $t9, $v0
jalr $t9 ; qfree
nop
lw $gp, 0x20+var_10($fp)
lw $v0, 0x20+var_4($fp)
addiu $v0, 1
sw $v0, 0x20+var_4($fp)
b loc_1770C
nop
# ---------------------------------------------------------------------------
loc_17760: # CODE XREF: free_argv(int,char **)+40↑j
lw $a0, 0x20+arg_4($fp)
lw $v0, (qfree_ptr-0x7FF0 - _GLOBAL_OFFSET_TABLE_)($gp)
move $t9, $v0
jalr $t9 ; qfree
nop
lw $gp, 0x20+var_10($fp)
loc_17778: # CODE XREF: free_argv(int,char **)+28↑j
nop
move $sp, $fp
lw $ra, 0x20+var_s4($sp)
lw $fp, 0x20+var_s0($sp)
addiu $sp, 0x28
jr $ra
nop
# } // starts at 176D864-bit comparison
Sorry for another long assembler listing. It shows that for MIPS, as for other platforms, the decompiler can recognize 64-bit operations and collapse them into very readable constructs.
Magic divisions
We recognize magic divisions for MIPS the same way as for other processors. Note that this listing has a non-trivial delay slot.
Hard cases with delay slots
The previous example was a piece of cake. This one shows a tougher nut to crack: there is a jump to a delay slot. A decent decompiler must handle these cases too and produce a correct output without misleading the user. This is what we do. (We spent quite long time inventing and testing various scenarios with delay slots).
Little-endian MIPS
We support both big-endian and little-endian code. Usually they look the same but there may be subtle differences in the assembler. The decompiler keeps track of the bits involved and produces human-readable code.
MicroMIPS
MicroMIPS, as you have probably guessed, is supported too, with its special instructions and quirks.
Floating-point operations
The MIPS processor contains a number of complex floating point instructions, which perform several operations at once. It is not easy to decipher the meaning of the assembler code but the pseudocode is the simplest possible.
Compiler helpers
A compiler sometime uses helpers; our decompiler knows the meaning of the many helpers and uses it to simplify code.
Last updated
Was this helpful?
