我尝试实现以下目标:我有一个指针p
指向一个再次保存地址的地址(该地址也是一个有效地址)。现在我想要另一个指针pp
指向p
的内容地址。所以我正在执行以下操作:
// Retrieve the start address
unsigned long long *p = getInitialAddress();
// Let pp point to next address
unsigned long long *pp = (unsigned long long*)(*p);
// Print address
printf("0x%llx %p\n", *p, pp);
这将打印例如:0x7fffedc47a70 0x7fffedc47a70
,这是所需的结果。
但是,将另一个 printf
放入代码中,如下所示:
// Retrieve the start address
unsigned long long *p = getInitialAddress();
// Print
printf("%p 0x%llx\n", p, *p);
// Let pp point to next address
unsigned long long *pp = (unsigned long long*)(*p);
// Print address
printf("0x%llx %p\n", *p, pp);
导致:
0x7fffacea3660 0x7fffacea3680
0x0 (nil)
这不是正确的结果,因为它应该是
0x7fffacea3660 0x7fffacea3680
0x7fffacea3680 0x7fffacea3680
那么 printf
是否改变了指针中的某些内容或者出了什么问题?
编辑:完整代码
unsigned long long* readRBP();
int main(void) {
// Retrieve the start address
unsigned long long *p = readRBP();
// Print
printf("%p 0x%llx\n", p, *p);
// Let pp point to next address
unsigned long long *pp = (unsigned long long*)(*p);
// Print address
printf("0x%llx %p\n", *p, pp);
return 0;
}
unsigned long long* readRBP() {
unsigned long long rbp;
__asm__ volatile("mov %%rbp, $0" : "=r"(rbp));
return (unsigned long long*)rbp;
}
这将获取 rbp(堆栈基指针)。这个指针的内容是指向下一个rbp的指针等等。 这个 rbp 来自 readRBP()
本身,下一个 rbp 属于 main
,main 之后的下一个 rbp 是 0x0
,岛。 e.一开始。
最佳答案
readRBP 返回的值是 readRBP 函数的基指针。然后,您调用 printf 创建自己的堆栈帧。该堆栈帧会删除 *p
处的数据。
要看到这一点,您就可以这样编写代码:
int main(void) {
// Retrieve the start address
unsigned long long *p = readRBP();
unsigned long long pContents = *p
unsigned long long *pp = (unsigned long long*)(*p);
// Print
printf("%p 0x%llx %p\n", p, pContents, pp);
return 0;
}
换句话说,您将所有信息收集到 main
的堆栈帧中,然后再通过调用 printf
来处理它。
关于printf 后将变量内容转换为指针结果为 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10154630/