long vframe(long n, long idx, long *q){
long i;
long *p[n];
p[0] = &i;
for(i=1; i<n; i++)
p[i]=q;
return *p[idx];
}
I have the vframe function and generated the assembly code like this
1: vframe:
2: pushq %rbp
3: movq %rsp, %rbp
4: subq $16, %rsp
5: leaq 22(, %rdi, 8), %rax # I think the number 22 is vary from machine and OS
6: andq $-16, %rax
7: subq %rax, %rsp
8: leaq 7(%rsp), %rax
9: shrq $3, %rax
10: leaq 0(, %rax, 8), %r8
11: movq %r8, %rcx
................................
12: L3:
13: movq %rdx, (%rcx, %rax, 8)
14: addq $1, %rax
15: movq %rax, -8(%rbp)
16: L2:
17: movq -8(%rbp), %rax
18: cmpq %rdi, %rax
19: jl L3
20: leave
21: ret
If we see lines from 8 to 11, we didn't push address of p on stack but assembly has already assumed &p[0] is in %rsp since leaq 0(, %rax, 8), %r8 means the instruction set %r8 to &p[0] (Actually I check variable i is moved to stack by checking my own compiler like movq $0x1,-0x8(%rbp) but I couldn't find about &p[0])
If we want some argument not to be corrupted, we push some register and move callee saved register to the pushed register. But ,in this case, it seems not. Is there any other conventions about local variable like i and &p[0] in this code? I mean why &p[0] is in %rsp even though we didn't push &p[0] on stack?