Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What syntax do I need to make the compiler put this variable on the stack?

I'm decompiling an old game that was ported to the PlayStation 2. The game was shipped as a debug build, and as a result has DWARF v1 debug data. The compiler used is Metrowerks CodeWarrior.

There's one function that's giving me trouble in matching it with the original assembly:

void sibi2() {
  short block_no, i;
  short* block_tbl;
  short* tbl[3] = { tate, yoko, naname };

  if (actwk[0].mstno.b.h == 43 || actwk[0].r_no0 >= 4
      || plpower_a != 0 || plpower_m != 0
      || ((short*)&actwk[0])[26] != 0 || st6clrchg == 0)
    return;

  block_tbl = tbl[st6clrchg - 1];
  block_no = scramapad(&actwk[0], actwk[0].xposi.w.h, actwk[0].yposi.w.h);
  block_no &= 2047;
  i = 0;
  while (block_tbl[i] >= 0) {
    if (block_no == block_tbl[i++]) {
      playdamageset(&actwk[0], &actwk[0]); break;
    }
  }
}

In the original assembly, the local variable block_tbl is located on the stack, right next to tbl. This was confirmed using the internal debugger of PCSX2, a PlayStation 2 emulator. However, when I compile this code, block_tbl is put in CPU register s0.

I've tried various variable placements and small code changes, but the only thing that made the compiler put the variable on the stack is to change its type from short* to short*[1]. However, this also causes the type in the debug data to change, so this is not what was originally written.

Does anyone have any idea what the code needs to look like? To make things easier, there's a decomp.me scratch where I've been trying to match the assembly.

like image 532
user16316067 Avatar asked Nov 22 '25 13:11

user16316067


1 Answers

Somewhat surprisingly, declaring block_tbl as short *volatile block_tbl seems to work fine (https://decomp.me/scratch/jU2yO - 99.69% match). The logic here is to make the pointer itself volatile, inhibiting some of the compiler assumptions that could otherwise cause it to store the variable in a register.

Note that I have not checked whether this affects the debug data; in principle, DWARF can represent the volatile modifier but not all compilers will actually output the volatile tag. It’s also probably not what was originally written by the developers, since it doesn’t seem to make much sense to make that particular variable volatile.


Another, somewhat simpler approach is just to take the address of block_tbl, which forces it to have a stack address. Since you’re compiling without optimizations, even a statement like (void)&block_tbl; is sufficient to force the compiler to use a stack variable (demo: https://decomp.me/scratch/fyAUr, also 99.69%). This has the advantage of not changing the type of the variable at all.

like image 70
nneonneo Avatar answered Nov 25 '25 02:11

nneonneo