初识堆栈

2018-12-21  本文已影响47人  豆瓣奶茶

什么是堆栈

引出堆栈

在学习堆栈之前,我们需要从之前寄存器和内存中引出堆栈,我们要思考堆栈有什么必要性?
现在假设我们需要一块内存,它可以满足如下功能

1.主要用于临时存储一些数据

  1. 能够记录存储了多少数据
  2. 可以很方便的找到需要的数据

对于第一条,有人说直接放寄存器不就可以了吗?但是如果我们有2个字节的数据,有5个字节的数据,都好说。但是如果我有几百,几千个数据呢?寄存器明显就不行了

还好有高人

还有在我们之前,有那么多厉害的人。有人设计出这样一块内存,虽然简单,但却刚好满足了上面我们的三个需求。

image.png
为了满足第二条,我们直接top-base;
对于第三条,比如我们存储了500个数据,我们需要第50个,我们直接base+50个单位的偏移就可以找到。突然又需要第200个数据,base+200单位的偏移就是。这里的单位是指byte

还需要注意一点,在window系统中堆栈是往低位扩展了,起初会选择一个值比较大的位置作为base,然后每次往低位扩展,top不断变小。

实验,自己实现堆栈

1.我们使用32位寄存器EBX和EDX作为栈顶和栈底 。

  1. 为了实验的方便,主要是DTDebug显示的方便。我们每次操作都操作4字节

压入数据


我们就选中内存地址0019FF74吧

MOV EBX,0019FF74  //栈底的内存地址(base)
MOV EDX,0019FF74  //栈顶的内存地址(top)

接下来我们有三种实现方式

方式一:

先存储数据,再移动栈顶

MOV DWORD PTR ds:[EDX-4],0xAAAAAAAA
SUB EDX,4

方式二:

先移动栈顶,再存储数据

SUB EDX,4
MOV DWORD PTR DS:[EDX],0xBBBBBBBB

方法三

先存储数据,再用LEA

mov dword ptr ds:[edx-4],0xCCCCCCCC
lea edx, dword ptr ds:[edx-4]

第二句话为什么不是这样lea edx,byte ptr ds:[edx-4],暂时没有明白?
不就是取地址吗?为了一定要4个字节呢?

方法四:

先lea,再存储数据


读取数据

读取第N个数

方式一

方式二

弹出数据

不光要读取栈顶的数据,还需要将栈顶的位置进行移动


image.png

操作系统实现的堆栈

堆栈是软件设计常用的概念。如果每次我们需要的时候,都需要自己手动实现,效率也太低了。
为此,操作系统联合cpu给我们实现了堆栈。如何联合的呢?
cpu提供两个32位的寄存器,ESP和EBP,一个用来存储宅顶,一个用来存储栈底。其实对于cpu来说,这两个寄存器和其他的寄存器并没有什么特殊的地方,只是操作系统按照自己的习惯把他两区别对待了。这两个就用来存储栈顶和栈底,相当于cpu和操作系统的之间的约定。(突然想到了协议)

那之前我们所有的操作就可以再两个命令代替了

入栈用push
出战用POP
上一篇下一篇

猜你喜欢

热点阅读