Skip to content

GCC 2.8.1 Tips and Tricks

Ethan Roseman edited this page Oct 11, 2021 · 11 revisions

This page lists patterns and problems that frequently show up when decomping, and how to go about matching them.

Target puts nop in delay slot instead of using it

      TARGET                       CURRENT
lui    a0, %hi(foo)          lui    a0, %hi(foo)
addiu  a0, %lo(foo)
jal    bar                   jal    bar
nop                          addiu  a0, %lo(foo)

This usually means foo is a .data or .rodata symbol of this file, rather than externed elsewhere. (TODO: could it be the other way around? alex has forgotten)

MULT_HI

This

f32 x;
MULT_HI(x, constant) >> shift

should be rewritten as

f32 x;
x / y

This issue lists the constants/shifts: https://github.com/NationalSecurityAgency/ghidra/issues/668

e.g. MULT_HI(x, 0x51EB851F) >> 5 is x / 10

Negative struct offsets in loops

You may see the asm do this:

void fx_73_update(EffectInstance* arg0) {
    SomeStruct* structTemp;
    s32 i;

    structTemp = arg0->data;

    if (arg0->numParts > 1) {
        structPlus20 = temp_a1 + 0x20;
        do {
            if (structPlus20->unk0 <= 0) {
                structPlus20->unk-1C--;
                if (structPlus20->unk-1C >= 0xA) {
                    structPlus20->unk0 = -1;
                }
            }
            i++;
            structPlus20 += 0x24;
        } while (i < arg0->numParts);
    }
}

Note the negative offsets (unk-1C, for example) and how phi_v1 is 0x20 bytes into the struct. You can calculate the correct offsets by taking the 0x20 and subtracting 0x1C to get unk_04. However, to get the code to actually generate these negative offsets, you need to increment the struct temp pointer as well as the normal loop iterator: for (i = 1; i < numParts; i++, part++) {

Clone this wiki locally