Files
BFM-decomp/cookbook/C0374.md
T

1.1 KiB

§333 — FRAME SIZE IS SET BY DECLARED AGGREGATES, NOT USED ONES: AN UNREFERENCED TRAILING LOCAL IS A REAL DIAL (P31 S67; three independent byte-proven instances in one wave)

gcc-2.7.2 slots every aggregate local in declaration order regardless of whether it is used, so a frame larger than the live locals explain is a DEAD trailing aggregate in the original source. This is a dial you set, not a residual you chase:

  • ov_SC03_121/func_8017D8D4 — three SVECTORs (sp+0x10/0x18/0x20) gave 0x30, target was 0x38. Declaring an unreferenced FOURTH SVECTOR last fixed 6 of 13 residuals.
  • ov_SC04_016/func_8017DF8C — an unused s32 pad[2] raised var_size 16 -> 24 and reproduced the target's 0x50 frame: worth 30 of 32 residual rows, because gcc allocates that slot before caller-save's and shifts all four spill offsets 0x10 -> 0x18.
  • ov_SC05_008/func_8017DF68 — needed 16 bytes of unreferenced aggregate locals at 0x28-0x37. Read it off the frame arithmetic first: if .frame exceeds what your declared live locals require, add the missing bytes as a trailing unused aggregate before touching anything else.