assembly - 问题理解如何从堆栈访问内存
问题描述
我正在尝试自学组装,并且在堆栈和访问堆栈之间的交互方面遇到了一些困难。我正在使用 x86 64 位系统,并且正在执行一个简单的程序,将 5 和 2 推入堆栈(按此顺序),然后调用一个函数。所以,如果字长是 2 个字节,那么我应该能够通过 [esp+2] 计算返回地址来得到 2。但是,我得到 0,因为当我使用 edg 并逐步执行时,值(通过将其移动到寄存器中)是 00000002000000 所以我可以使用 [esp+8] 访问它,然后使用 [esp+16] 访问它,但是,那是否意味着字长为 4?那么这是否意味着单词的大小取决于系统的位?甚至只是使用的寄存器呢?而是因为堆栈的每个段的大小在 64 位系统上是 8 个字节?
解决方案
而是因为堆栈的每个段的大小在 64 位系统上是 8 个字节?
是的。
当你推送这些东西然后调用一个函数时,这是你的堆栈:
+-----------------+
| 5 | RSP+0x10
+-----------------+
| 2 | RSP+0x08
+-----------------+
| Return Addr | RSP+0x00
+-----------------+
同样,在 32 位系统上,您正在为您的堆栈查看此内容:
+-----------------+
| 5 | ESP+0x08
+-----------------+
| 2 | ESP+0x04
+-----------------+
| Return Addr | ESP+0x00
+-----------------+
顺便说一句,请记住 64 位寄存器以 R(RSP
、、RAX
等)开头。此外,根据您的操作系统,您可能会错误地通过堆栈传递参数。64 位系统对前 N 个参数使用寄存器,然后从那时起使用堆栈。根据您是传递整数/指针还是浮点数,寄存器会有所不同。出于您的目的,使用 SystemV,前 6 个通过RDI
、RSI
、RDX
、RCX
和R8
(按此R9
顺序)传递。64 位 Windows 使用RCX
、RDX
和前 4 个(R8
按此R9
顺序)。这在您学习时并不重要,但随着您开始调用其他模块/OS API,它会变得越来越重要。
推荐阅读
- python-3.x - 停用 salesforce 用户
- python - 如何一次保存多个图层修改
- reactjs - 使用 Apollo/GraphQL 在标头中发送 JWT
- google-cloud-platform - 限制谷歌云端点
- vba - 用户更改父下拉菜单时如何重置下拉菜单?
- formatting - 如何在高级 PDF 装箱单上缩进套件组件项目
- sql - 如何更新此查询以使用 listagg 而不是 wm_concat?
- reactjs - 反应原生列表列表中的每个孩子都应该有一个唯一的“关键”道具
- c# - 如何在 C# 中创建一个动态的 int 指针数组?
- python - 如何在 Ubuntu 上彻底清理或重置 Python 安装