首页 > 解决方案 > 问题理解如何从堆栈访问内存

问题描述

我正在尝试自学组装,并且在堆栈和访问堆栈之间的交互方面遇到了一些困难。我正在使用 x86 64 位系统,并且正在执行一个简单的程序,将 5 和 2 推入堆栈(按此顺序),然​​后调用一个函数。所以,如果字长是 2 个字节,那么我应该能够通过 [esp+2] 计算返回地址来得到 2。但是,我得到 0,因为当我使用 edg 并逐步执行时,值(通过将其移动到寄存器中)是 00000002000000 所以我可以使用 [esp+8] 访问它,然后使用 [esp+16] 访问它,但是,那是否意味着字长为 4?那么这是否意味着单词的大小取决于系统的位?甚至只是使用的寄存器呢?而是因为堆栈的每个段的大小在 64 位系统上是 8 个字节?

标签: assemblyx86-64cpu-registerscallstack

解决方案


而是因为堆栈的每个段的大小在 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 个通过RDIRSIRDXRCXR8(按此R9顺序)传递。64 位 Windows 使用RCXRDX和前 4 个(R8按此R9顺序)。这在您学习时并不重要,但随着您开始调用其他模块/OS API,它会变得越来越重要。


推荐阅读