1
所以我目前正在学习堆栈帧,并且我想实验打印函数的堆栈帧(手动)。打印堆栈帧
我有一个堆栈帧的心下面的图片(I可能是错误的):
| | 0xffff0fdc
+--------------------------------+
| ... | 0xffff0fd8
+--------------------------------+
| parameter 2 | 0xffff0fd4
+--------------------------------+
| parameter 1 | 0xffff0fd0
+--------------------------------+
| return address | 0xffff0fcc
+--------------------------------+
| local variable 2 | 0xffff0fc8
+--------------------------------+
| local variable 1 | 0xffff0fc4
+--------------------------------+
因而我第一次写这个函数来实现上述结果和打印:
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;
}
,我得到:
0
12884901890
51266344552759297
18034967110614932
绝对不是什么预期
我也试过“扫描”通过烟囱找到论据之一:
while (*sp != a) sp++
但没有成功。我的方法有什么问题?
我也有另外一个问题: 给出一个递归函数,采取简单的阶乘(INT N),我们怎么能点其中基本指针位于堆栈中的地址?
的情况下,你需要的汇编代码: 注意,这仅包含生成的汇编代码的函数“功能”。 我在汇编代码与源代码相关的地方添加了注释。
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
任何意见,以帮助我更好地处理堆栈将不胜感激!
PS:我是不允许使用任何外部函数
这是完美的,非常感谢! :) –