So I am currently learning about stack frames, and I wanted to experiment printing the stack frame (manually) of a function.
I have the following picture in mind of a stack frame (I may be wrong):
| | 0xffff0fdc
+--------------------------------+
| ... | 0xffff0fd8
+--------------------------------+
| parameter 2 | 0xffff0fd4
+--------------------------------+
| parameter 1 | 0xffff0fd0
+--------------------------------+
| return address | 0xffff0fcc
+--------------------------------+
| local variable 2 | 0xffff0fc8
+--------------------------------+
| local variable 1 | 0xffff0fc4
+--------------------------------+
thus I first wrote this function to achieve the above result and print it :
void func(int a,int b)
{
uint64_t loc = 0;
uint64_t *sp = &loc;
printf("%" PRIu64 "\n",*(sp));
printf("%" PRIu64 "\n",*(sp+4));
printf("%" PRIu64 "\n",*(sp+8));
printf("%" PRIu64 "\n",*(sp+12));
}
int main()
{
func(2,3);
return 0;
}
and I get :
0
12884901890
51266344552759297
18034967110614932
definitely not what was expected
I also tried "scanning" through the stack to find one of the argument :
while (*sp != a) sp++
without much success. What is wrong with my method ?
I also had another question : Given a recursive function, take simply factorial(int n), how could we spot the address where the base pointer is located in the stack ?
in case you need the assembly code : Note that this only contains the function "func" generated assembly code. I added comments to where the assembly code relates to the source code.
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movl %edi, -20(%rbp)
movl %esi, -24(%rbp)
***// uint64_t loc = 0;***
movq $0, -16(%rbp)
***// uint64_t *sp = &loc;***
leaq -16(%rbp), %rax
movq %rax, -8(%rbp)
***// printf("%" PRIu64 "\n",*sp);***
movq -8(%rbp), %rax
movq (%rax), %rax
movq %rax, %rsi
movl $.LC0, %edi
movl $0, %eax
call printf
***printf("%" PRIu64 "\n",*(sp+8));***
movq -8(%rbp), %rax
addq $64, %rax
movq (%rax), %rax
movq %rax, %rsi
movl $.LC0, %edi
movl $0, %eax
call printf
***// printf("%" PRIu64 "\n",*(sp+16));***
movq -8(%rbp), %rax
subq $-128, %rax
movq (%rax), %rax
movq %rax, %rsi
movl $.LC0, %edi
movl $0, %eax
call printf
***// printf("%" PRIu64 "\n",*(sp+32));***
movq -8(%rbp), %rax
addq $256, %rax
movq (%rax), %rax
movq %rax, %rsi
movl $.LC0, %edi
movl $0, %eax
call printf
leave
.cfi_def_cfa 7, 8
ret
Any advices to help me undertand the stack better would be greatly appreciated!
PS : I am not allowed to use any external functions