Really bizarre gcc quirk. Check this out:
main() { int a[100]; a[0]=1; }
produces this assembly:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 81 ec 18 01 00 00 sub $0x118,%rsp
b: c7 85 70 fe ff ff 01 movl $0x1,-0x190(%rbp)
12: 00 00 00
15: c9 leaveq
16: c3 retq
The top of the stack is clearly 400, since its a 100 * 4 array. So when it writes to the first entry, it does rbp - 400 (line 'b'). Good. But why does it subtract 280 from the stack (line '4') pointer? Doesn't that point to the middle of the array?
If we add a function call afterward, gcc does the right thing:
b() {}
main() { int a[100]; a[0]=1; b(); }
produces this assembly:
0000000000000000 <b>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: c9 leaveq
5: c3 retq
0000000000000006 <main>:
6: 55 push %rbp
7: 48 89 e5 mov %rsp,%rbp
a: 48 81 ec 90 01 00 00 sub $0x190,%rsp
11: c7 85 70 fe ff ff 01 movl $0x1,-0x190(%rbp)
18: 00 00 00
1b: b8 00 00 00 00 mov $0x0,%eax
20: e8 00 00 00 00 callq 25 <main+0x1f>
25: c9 leaveq
26: c3 retq
Here, it properly subtracts 400 (line 'a').
Why the change when you add a function call? Is gcc just lazy, and doesn't do it right because it doesn't matter? What's happening? Evidently this only happens when compiling for x86_64, but not for plain x86. Does this have something odd to do with x86_64's "redzone"? What's happening precisely?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…