问题了解如何从堆栈访问内存

时间:2019-05-31 01:08:22

标签: assembly x86-64 cpu-registers callstack

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

1 个答案:

答案 0 :(得分:3)

  

是不是因为在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开头(RSPRAX等)。另外,根据您的操作系统,您可能会错误地通过堆栈传递参数。 64位系统将寄存器用于前N个参数,然后使用堆栈。寄存器是不同的,具体取决于您传递的是整数/指针还是浮点数。为了您的目的,使用SystemV,前6个通过RDIRSIRDXRCXR8R9传递订购)。 64位Windows的前4个(按该顺序)使用RCXRDXR8R9。现在,在学习时这并不重要,但是随着您开始调用其他模块/ OS API,它将变得越来越重要。