问题理解如何从堆栈访问内存
Issue understanding how to access memory from the stack
我正在尝试自学汇编,但在堆栈和访问堆栈之间的交互方面遇到了一些困难。我正在使用 x86 64 位系统,并且正在执行一个简单的程序,将 5 和 2 压入堆栈(按该顺序),然后调用一个函数。所以,如果字的大小是 2 个字节,那么我应该可以通过 [esp+2] 计算 return 地址来达到 2。但是,我得到 0 是因为当我使用 edg 并单步执行时,值(通过将其移动到寄存器中)为 00000002000000 因此我可以使用 [esp+8] 访问它,然后使用 [esp+16] 访问它 5 但是,是否意味着字长为 4?那么这是否意味着字的大小取决于系统的位?甚至只是使用的寄存器呢?而是因为在 64 位系统上堆栈的每个段的大小是 8 个字节?
Instead is it because the size for each segment of the stack is 8 bytes on a 64 bit system?
是的。
当你推送这些东西然后调用一个函数时,这是你的堆栈:
+-----------------+
| 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 个参数使用寄存器,然后使用堆栈。根据您传递的是 integers/pointers 还是浮点数,寄存器会有所不同。出于您的目的,对于 SystemV,前 6 个通过 RDI
、RSI
、RDX
、RCX
、R8
和 R9
传递(在那命令)。 64 位 Windows 使用 RCX
、RDX
、R8
和 R9
作为前 4 个(按此顺序)。这在您学习时并不重要,但随着您开始调用其他 modules/OS API,它会变得越来越重要。
我正在尝试自学汇编,但在堆栈和访问堆栈之间的交互方面遇到了一些困难。我正在使用 x86 64 位系统,并且正在执行一个简单的程序,将 5 和 2 压入堆栈(按该顺序),然后调用一个函数。所以,如果字的大小是 2 个字节,那么我应该可以通过 [esp+2] 计算 return 地址来达到 2。但是,我得到 0 是因为当我使用 edg 并单步执行时,值(通过将其移动到寄存器中)为 00000002000000 因此我可以使用 [esp+8] 访问它,然后使用 [esp+16] 访问它 5 但是,是否意味着字长为 4?那么这是否意味着字的大小取决于系统的位?甚至只是使用的寄存器呢?而是因为在 64 位系统上堆栈的每个段的大小是 8 个字节?
Instead is it because the size for each segment of the stack is 8 bytes on a 64 bit system?
是的。
当你推送这些东西然后调用一个函数时,这是你的堆栈:
+-----------------+
| 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 个参数使用寄存器,然后使用堆栈。根据您传递的是 integers/pointers 还是浮点数,寄存器会有所不同。出于您的目的,对于 SystemV,前 6 个通过 RDI
、RSI
、RDX
、RCX
、R8
和 R9
传递(在那命令)。 64 位 Windows 使用 RCX
、RDX
、R8
和 R9
作为前 4 个(按此顺序)。这在您学习时并不重要,但随着您开始调用其他 modules/OS API,它会变得越来越重要。