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 176D8

64-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.

# =============== S U B R O U T I N E =======================================

# Attributes: bp-based frame fpd=0x18

# _DWORD uh_eq_s(void)
                .globl _Z7uh_eq_sv
_Z7uh_eq_sv:                             # DATA XREF: .eh_frame:000478E4↓o

var_s0          =  0
var_s4          =  4
var_s8          =  8
var_sC          =  0xC
var_s10         =  0x10
var_s14         =  0x14
var_s18         =  0x18
var_s1C         =  0x1C

 # __unwind {
                addiu   $sp, -0x38
                 sw      $ra, 0x18+var_s1C($sp)
                 sw      $fp, 0x18+var_s18($sp)
                 sw      $s5, 0x18+var_s14($sp)
                 sw      $s4, 0x18+var_s10($sp)
                 sw      $s3, 0x18+var_sC($sp)