- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我无法理解堆栈的工作原理。首先是我的小代码:
void func1 ( int z ) {
int i = 1;
}
int main ( ) {
func1 ( 89 );
return 0;
}
我正在使用:Ubuntu 16.04 64 位,gcc 版本 5.4.0,gdb 版本 7.11.1。
我正在使用 GDB 进行调试,以查看编译器如何将函数参数压入堆栈。
当我在 RSP 指向的位置检查堆栈时,我得到了这个:
(gdb) x/10xw $rsp
0x7fffffffdf20: 0xffffdf30 0x00007fff 0x00400525 0x00000000
0x7fffffffdf30: 0x00400530 0x00000000 0xf7a2e830 0x00007fff
0x7fffffffdf40: 0x00000000 0x00000000
当我打印出最新创建的变量的地址时,我得到了这个:
(gdb) p &i
$4 = (int *) 0x7fffffffdf14
当我打印出移交给函数的变量地址时,我得到了这个:
(gdb) p &z
$5 = (int *) 0x7fffffffdf0c
堆栈越来越小。
所以我认为 RSP
总是指向堆栈的顶部,这意味着当我调用此命令时 x/10xw $rsp
我能够看到所有函数中的变量,但我无法从那里看到它们。
此命令后的首地址远高于变量z
的地址。因此,我猜测 RSP
点不在堆栈的顶部。
同样让我感到奇怪的是,i
的地址高于 z
的地址。由于 i
比 z
晚入栈,所以我认为 i
必须是比 z 低的地址。
我希望有人能解释一下为什么会这样。
编辑:我找到了答案!这是编译器的优化。在 func1()
中,RSP
寄存器没有指向堆栈的“顶部”,因为这不是必需的。如果在 func1()
中调用了另一个函数,则这是必要的。所以编译器看到了并且没有递减 RSP
寄存器。
这是我的汇编代码,在 func1()
中没有函数调用:
0x00000000004004d6 <+0>: push rbp
0x00000000004004d7 <+1>: mov rbp,rsp
0x00000000004004de <+8>: mov DWORD PTR [rbp-0x14],edi
0x00000000004004e1 <+11>: mov DWORD PTR [rbp-0x4],0x1
0x00000000004004e8 <+18>: mov eax,0x0
0x00000000004004f3 <+29>: leave
0x00000000004004f4 <+30>: ret
所以您看不到 SUB
调用递减 RSP
。
现在来自 func1()
的代码带有一个函数调用:
0x00000000004004d6 <+0>: push rbp
0x00000000004004d7 <+1>: mov rbp,rsp
0x00000000004004da <+4>: sub rsp,0x20
0x00000000004004de <+8>: mov DWORD PTR [rbp-0x14],edi
0x00000000004004e1 <+11>: mov DWORD PTR [rbp-0x4],0x1
0x00000000004004e8 <+18>: mov eax,0x0
0x00000000004004ed <+23>: call 0x4004f5 <func2>
0x00000000004004f2 <+28>: nop
0x00000000004004f3 <+29>: leave
0x00000000004004f4 <+30>: ret
因此您可以看到 SUB
调用递减 RSP
。所以RSP
可以指向“top”。
最佳答案
x86 上的约定是堆栈“向下”增长以减少地址。
堆栈的“顶部”只是最近被推送的位置;它不是基于地址的相对值。堆栈可以在地址空间中“向上”或“向下”增长 - 哎呀,对于某些实现(例如链表),地址甚至不必是连续的。
This page有图表的公平解释。
关于c - RSP 不指向栈顶?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40349105/
php应用越来越多,也越来越广泛,为了增加网站的丰富多彩,从而出现了很多新的技术。ajax是现代网站中不能缺少的一项技术,他可以异步刷新数据,而实现很多效果,比如刷新验证码,微博中的赞功能,都是运用
我想在用户将tableView滚动到顶部时进行分页,因为我已经使用了这种UIScrollView方法。但是它将多次调用api 最佳答案 不好意思 当服务器提供数据计数数量 -(void)tableVi
我有以下 swift 代码,我想要实现的是从顶部滑出的 segue。我希望第二个 VCView 位于第一个 VCView 下方,并且让第一个 VCView 滑出显示第二个 VCView。 目前没有动画
我正在使用 ECSliding我有这个问题! 在我的项目中有这个文件: InitViewController (ECSlidingController) FirstViewController (UI
当我们浏览网页时,我们想对网页内容如文章、评论中的观点持赞同或反对意见时,可以通过点击网页中的“顶”和“踩”来进行投票。而整个交互过程,开发者可以通过ajax异步来实现,从而提高用户体验
您好,我遇到了这样的问题, 我有两个 View ,例如我的第一个 View 是 A,其图像如下所示 我正在这个 View A 上打开 View B 例如,当我触摸没有按钮的区域时,在 View B 中
我正在尝试从图像生成鸟瞰图。对于相机固有特性和畸变,我使用的是从驾驶模拟器中检索到的硬编码值,该驾驶模拟器的车顶上安装了相机。 代码的基础来自“使用 OpenCV 库学习 OpenCV 计算机视觉”,
我正在尝试使用 Linux perf 进行一些性能分析。我有一个构建时去掉了符号的应用程序,令我惊讶的是 Linux perf top 无法显示 disassmbly 行。它只显示原始 EIP。 我们
本文实例为大家分享了基于PHP+jQuery+MySql实现红蓝(顶踩)投票代码,供大家参考,具体内容如下 数据库操作: ?
我正在使用 VueJS 和 Bootstrap 开发应用程序。我试图将一个 div 与图像居中,同时让复选框标 checkout 现在右上角,如下所示。 但是当鼠标悬停在卡片上时,图像会稍微向左移动,
我是一名优秀的程序员,十分优秀!