gccのアセンブリ出力を読んでみよう。

% cat main.c
int main(){exit(0);}
% gcc main.c -S -Os
% cat -n main.s
1: #.file 1 "main.c"
2: .set nobopt
3: .option pic2
4: .section .text,0x1,0x6,4,4
5: .text
6: .align 2
7: .globl main
8: .ent main
9: main:
10: .LFB3:
11: .frame $sp,32,$31 # vars= 0, regs= 2/0, args= 0, extra= 16
12: .mask 0x90000000,-8
13: .fmask 0x00000000,0
14: subu $sp,$sp,32
15: .LCFI0:
16: sd $31,24($sp)
17: .LCFI1:
18: sd $28,16($sp)
19: .LCFI2:
20: .set noat
21: lui $1,%hi(%neg(%gp_rel(main)))
22: addiu $1,$1,%lo(%neg(%gp_rel(main)))
23: daddu $gp,$1,$25
24: .set at
25: move $4,$0
26: la $25,exit
27: jal $31,$25
28: .LFE3:
29: .end main
腐った俺にわかるのは、14行目でsubu $sp,$sp,32として32バイト分スタックフレームを確保しているということくらいです。.frame $sp,32,$31 # vars= 0, regs= 2/0, args= 0, extra= 16というのは何か大きなヒントのような気がするんですけど、たいして調べる気もありません。

test