assembly - 使用前关于堆栈的假设
问题描述
在使用堆栈之前是否需要“清除”堆栈?换句话说,在使用堆栈之前,是否可以安全地假设它完全为零,或者它是垃圾并且它可以是任何东西?例如,假设我将一个三字节值移动AA AA AA
到%rbp-4
:
---------------------- %rsp / %rbp
---------------------- -1
AA
---------------------- -2
AA
---------------------- -3
AA
---------------------- -4
如果我将四个字节移动到一个寄存器中,例如:
movl -4(%rbp), %eax
我是否首先需要清除堆栈上未使用的字节,还是我们确定堆栈已被清除?
解决方案
...在使用堆栈之前,假设它完全归零是否安全...
在几乎所有用例中,堆栈在您使用之前就已经“使用”过了。
示例 C 代码:
void someFunction(void)
{
someOtherFunction();
functionIHaveWritten();
}
假设堆栈指针的初始值为rsp=0x10F000
.
现在该函数someOtherFunction()
将使用堆栈,将堆栈指针更改为另一个值(比如说rsp=0x10EF00
)并将一些数据(通常是局部变量)存储到 和 之间的内存0x10EF00
区域0x10F000
。
当函数someOtherFunction()
返回时,它会将栈指针恢复为rsp=0x10F000
,但不会清除栈上被函数覆盖的字节。
清除没有任何意义——这会花费时间,而且大多数函数不需要清除堆栈。
所以当你写的函数functionIHaveWritten()
——被调用的时候,栈里面就包含了这个函数写的“垃圾” someOtherFunction()
。
在使用堆栈之前是否需要“清除”堆栈?
如果要确保堆栈上的所有字节都初始化为零:是。
但是,在大多数情况下,您不需要这样做。
推荐阅读
- css - 在 iPhone 上使用 CSS 自定义属性定义 div background-image 时闪烁
- hangouts-chat - 如何在卡片消息 Google Chat API 中添加条件内容?
- zig - 使用 Zig 进行简单的日志分析
- javascript - 节点执行命令行,说它失败了。但它没有
- mysql - 雄辩的ORM右连接查询laravel中的数据透视表
- android - 在 Android 11 中可以使用文件夹打开文件管理器吗?
- php - 无法从 docker 容器中的 php 连接到远程 mysql 数据库
- reactjs - 使用 React fetch 给出了 pyramid.exceptions.PredicateMismatch: The resource could not be found
- r - 在 ggplot2 中编辑条形图
- git - @Jupyterlab/git - 无法克隆存储库