堆栈指针指向x86-CPU的确切位置(!)?到顶部元素还是右边呢?

时间:2017-11-14 23:53:03

标签: assembly stack cpu-architecture cpu-registers stack-pointer

在一些教程中,据说堆栈指针指向堆栈的顶部元素:

+-------------+
|    stack    |
+-------------+
| top element |  <-- esp
+-------------+

在其他人中,据说它指向它后面,所以第一个内存地址可以在堆栈增长时写入。

+-------------+
|    stack    |
+-------------+
| top element | 
+-------------+  <-- esp

在这个德国Wickipedia网站上 https://de.wikipedia.org/wiki/Register_(Computer)#Stapelregister 据说两个版本都存在,并且它取决于CPU架构。

我的问题是,它是如何在x86-CPU上运行的?它还取决于操作系统吗?

1 个答案:

答案 0 :(得分:2)

让我们假设您处于32b x86模式,并且您将地址100到200的内存保留为堆栈(不真实,太低,会与IVT发生冲突,但会为此示例)。堆栈中已经存在一些值,因此esp为160。

现在&#34;堆栈值的顶部&#34;占用地址160,161,162和163处的存储器(四个字节,因为在32b模式中,堆栈中的单个值是32b = 4B大),让我们说存储值0xaabbccdd

如果您现在push 0x12345678,则CPU将首先从esp - &gt;中减去4。新esp = 156; (160-4)。然后它将写入32b值,以小端方式分解为四个字节:mem[156] = 0x78, mem[157] = 0x56, mem[158] = 0x34, mem[159] = 0x12

现在,如果您将执行mov eax,[esp],它将从地址156加载32位值,这意味着它将从地址156,157,158,159的四个字节组成32b值到dword值0×12345678。

最后,当您在推送后查看调试器中的内存,从ss:esp地址查看它时,它将包含这些字节(hexa):

0000009C:  78 56 34 12 DD CC BB AA ....

(0x9C = 156 =内存视图开始的地址)。 esp点在值的第一个字节处,被认为是&#34;堆栈顶部&#34;。

或者当您将内存视图切换为显示dword值时,为避免小头编写,请显示:

0000009C:  12345678 AABBCCDD ....