I hace a question about gcc allocate memory for a variant array. If the C code is like below.
long vframe(long idx, long n, long *q) {
long i = 1;
long *p[n];
p[0] = & i;
for (i = 1; i < n; i++) {
p[i] = q;
}
return *p[idx];
}
With gcc and objdump I can get its assembly code, like below:
0000000000001139 <vframe>:
1139: 55 push %rbp
113a: 48 89 e5 mov %rsp,%rbp
113d: 53 push %rbx
113e: 48 83 ec 48 sub $0x48,%rsp
1142: 48 89 7d c8 mov %rdi,-0x38(%rbp)
1146: 48 89 75 c0 mov %rsi,-0x40(%rbp)
114a: 48 89 55 b8 mov %rdx,-0x48(%rbp)
114e: 48 89 e0 mov %rsp,%rax
1151: 48 89 c6 mov %rax,%rsi
1154: 48 c7 45 d8 01 00 00 movq $0x1,-0x28(%rbp)
115b: 00
115c: 48 8b 45 c0 mov -0x40(%rbp),%rax
1160: 48 8d 50 ff lea -0x1(%rax),%rdx
1164: 48 89 55 e8 mov %rdx,-0x18(%rbp)
1168: 48 89 c2 mov %rax,%rdx
116b: 49 89 d0 mov %rdx,%r8
116e: 41 b9 00 00 00 00 mov $0x0,%r9d
1174: 48 89 c2 mov %rax,%rdx
1177: 48 89 d1 mov %rdx,%rcx
117a: bb 00 00 00 00 mov $0x0,%ebx
117f: 48 8d 14 c5 00 00 00 lea 0x0(,%rax,8),%rdx
1186: 00
1187: b8 10 00 00 00 mov $0x10,%eax
118c: 48 83 e8 01 sub $0x1,%rax
1190: 48 01 d0 add %rdx,%rax
1193: bb 10 00 00 00 mov $0x10,%ebx
1198: ba 00 00 00 00 mov $0x0,%edx
119d: 48 f7 f3 div %rbx
11a0: 48 6b c0 10 imul $0x10,%rax,%rax
11a4: 48 29 c4 sub %rax,%rsp
11a7: 48 89 e0 mov %rsp,%rax
11aa: 48 83 c0 07 add $0x7,%rax
11ae: 48 c1 e8 03 shr $0x3,%rax
11b2: 48 c1 e0 03 shl $0x3,%rax
11b6: 48 89 45 e0 mov %rax,-0x20(%rbp)
11ba: 48 8b 45 e0 mov -0x20(%rbp),%rax
11be: 48 8d 55 d8 lea -0x28(%rbp),%rdx
11c2: 48 89 10 mov %rdx,(%rax)
11c5: 48 c7 45 d8 01 00 00 movq $0x1,-0x28(%rbp)
11cc: 00
11cd: eb 1c jmp 11eb <vframe+0xb2>
11cf: 48 8b 55 d8 mov -0x28(%rbp),%rdx
11d3: 48 8b 45 e0 mov -0x20(%rbp),%rax
11d7: 48 8b 4d b8 mov -0x48(%rbp),%rcx
11db: 48 89 0c d0 mov %rcx,(%rax,%rdx,8)
11df: 48 8b 45 d8 mov -0x28(%rbp),%rax
11e3: 48 83 c0 01 add $0x1,%rax
11e7: 48 89 45 d8 mov %rax,-0x28(%rbp)
11eb: 48 8b 45 d8 mov -0x28(%rbp),%rax
11ef: 48 39 45 c0 cmp %rax,-0x40(%rbp)
11f3: 7f da jg 11cf <vframe+0x96>
11f5: 48 8b 45 e0 mov -0x20(%rbp),%rax
11f9: 48 8b 55 c8 mov -0x38(%rbp),%rdx
11fd: 48 8b 04 d0 mov (%rax,%rdx,8),%rax
1201: 48 8b 00 mov (%rax),%rax
1204: 48 89 f4 mov %rsi,%rsp
1207: 48 8b 5d f8 mov -0x8(%rbp),%rbx
120b: c9 leave
120c: c3 ret
Here is the part I do not understand: Why do we still need to set %rax's lower 3bits to 0, even after we make sure %rax is %rsp sub a number which is a multiple of 16. Does that mean the %rsp may be a number which is not a multiple of 8? If so, in which case does that happen?
11a4: 48 29 c4 sub %rax,%rsp
11a7: 48 89 e0 mov %rsp,%rax
11aa: 48 83 c0 07 add $0x7,%rax
11ae: 48 c1 e8 03 shr $0x3,%rax
11b2: 48 c1 e0 03 shl $0x3,%rax