2009-10-29 59 views
1

所以我一直在学习汇编,来到堆栈的主题,存储本地,静态和全局变量和东西。事情如何存储在堆栈中?

但我很难想象它在我脑海中。

底部的内存,但顶部的堆栈,:S whaa?

让我感到困惑的是,每当有东西被推入堆栈时,堆栈指针就会被减去。它不应该添加到它。

我的意思是我得到的代码,但它很难不知道真的发生了什么。

回答

7

这是事实,许多CPU架构堆栈指针下降当事情是到堆栈中。这是真正的CPU的实现细节,但如果你觉得还不清楚,你可以试着想象堆就像是这个图上完成:

68000 CPU stack http://www.eventhelix.com/RealtimeMantra/Basics/CToAss1.gif

的内存,你下移地址增加,但是当你想东西在顶部你把它放在顶部(在一个较低的地址)。

(上图可以在EventHelix.com找到。)

+0

+1用于说明。 – outis

+0

这真棒,感谢图 – saint

+0

至于什么点将堆栈溢出? – Moak

2

将其视为实施细节。在许多体系结构中,当您将某些东西推入堆栈时,堆栈指针会被减去,以使堆栈向下(向较小的地址)增长。就这样。

2

他们之所以这样做是因为堆栈与堆共享相同的内存块。堆栈从顶部(低地址)增长到底部(高地址数量),堆栈从底部(高地址)增长到顶部(底部)。

这样做是为了不需要预测两次内存量(一个用于堆而另一个用于堆栈)。

00000000 HEAP---- 
00000001 |||||||| 
00000002 vvvvvvvv 

FFFFFFFD ^^^^^^^^ 
FFFFFFFE |||||||| 
FFFFFFFF Stack 

希望这会有所帮助。

1

减少SP的原因很简单:(*)堆栈被添加到“从底部”(关于内存位置)。这将有点像你有一个“待办事项列表”。您可以在页面顶部开始它,而不是在列表中随意标记单个项目(就像我们通常所做的那样),您只需启动并完成页面最远的任务即可。

使用堆栈顶部(即从较高地址)的内存的原因是,它允许另一个重要的内存存储,堆在另一个方向上增长(至少,这是在一些内存模型)。继续进行“待办事项列表”类比,现在您还将在页面底部写另一个列表,例如购物清单。但是,这个列表是堆的,你可以让自己在任意地方随意擦除东西,当你穿过商店时,以及重新使用一些被擦除线条留下的空间。

现在冒着为混乱添加更多材料的风险,堆栈管理的另一个重要元素是stack frame的概念,这是一种将参数存储到函数和局部变量的便捷方式,对应于嵌套函数调用的“整体上下文”。

(*)在许多CPU上,也就是说。正如Pierr指出的那样,有些CPU与一个堆栈一起工作,当事物被推动时,它将SP“向上”(增加)。

3

让我感到困惑的事情是,每当有东西被压入堆栈,堆栈指针就会被减去。它不应该添加到它。

它可能是。这取决于堆栈是向上还是向下扩展。

Understand the stack

Stack grow direction

+0

非常有帮助的链接,谢谢! – saint

0

堆栈向下增长,堆长大,这样你就不必决定多少每个。事实上,现在的情况比现在更复杂,但x86和其他公司都有机器操作,并且内置了这个假设。无论如何,这并不重要,机器的增加和减少同样好。

0

堆栈的“顶部”与堆栈在内存中的布局无关。

这是一个数据结构。 “堆栈”类比是一个概念模型,它在内存空间中向上或向下增长的事实只是一个实现细节。哎呀,它使用连续的内存块的事实仅仅是一个实现细节;例如,如果您将它作为链接列表实现,那么您可以有一个堆栈,其中的项目遍布整个地方。

它甚至不是一个真正的堆栈:例如,考虑到即使该教科书说它是“后进先出”,您实际上可以在堆栈中间更改项目。

你需要实现一个堆栈是什么:

  • 的一种方式指向每一帧堆栈
  • 指向堆栈的最后一个插入的元素的一种方式的/件(又名栈顶)
  • 一种方式来获得到前一个元素
  • 插入到最后一个元素的一种方法/顶
  • 以除去年底/顶部的元素,使得它的前一个元素,成为新的最后/ top元素。

内存布局如何看起来与任何它没有任何关系。