汇编笔记 之二 栈

上次只是大概了说了一下栈。现在我们来详细的了解下栈。

            什么是栈呢,栈并非真的存在,只是CPU的一种处理机制。一个很恰当的比喻就是。如果你把米倒进米缸,那么如果你要用米的话,首先用的将是你后倒进去的米。也就是先进后出的方式。

            那么,我们怎么让CPU知道那个段地址是栈呢,很显然需要一个指示,也就是说,需要指定一段地址告诉CPU,这段地址是栈。也许我们会想到,用2个寄存器表示栈顶,2个表示栈底。这样CPU就可以明确的知道了。可是事实并非如此。CPU只用了2个寄存器用来标识栈段。SS:SP。并没有告诉我们栈底,只告诉我们 SS:SP指向的地址是栈顶。一个栈段是我们自己定义并需要在操作的时候注意的问题。就是栈越界的问题。

        栈操作只有2种,在第一次笔记里面就有了,出栈和入栈。

       出栈:pop ax;

                将SS:SP里面的数据传送到ax ,SP 中的数据加2

       入栈:push ax;

                将SP中的数据减2 ,并将ax中的数据传送到栈顶。

             如果,我们将20000 ~ 2000FH作为栈来使用,那么,遵循SS:SPS使用指向栈顶的原则。规定SS = 2000 ,那么SP = 10H。为什么是10H呢,也许很多人都不明白。我当时也不是很明白,为什么呢。大家想想,如果栈中有一个元素 2233H,那么 SS = 2000  SP = EH ,因为 2233H占2个字节,也就是一个字。所以SP = EH ,也就是说现在栈中只有1个元素,现在将最后一个元素出栈,也就是 pop ax 这时,SP + 2 = E + 2  = 10H ,所以 SP 在栈空的时候是 10H,而不是FH 。

            下面是代码:

1   mov ax,2000h ; 将数据2000H传送到ax寄存器,字操作。
2
3 mov ss,ax; 将ax寄存器里面的内容传送到ss段寄存器。
4
5 mov sp,10h;将10h传送到数据寄存器sp,初始化栈顶。
6
7

            明白了栈操作,现在我们来考虑,如果,栈中最后一个元素出栈了,我们继续出栈,会有什么情况发生。也就是说将不是我们预计的内存地址的数据传送出来。也许这个情况你们还看不出什么问题。但是,如果栈底,我们继续入栈。也就是说,我们将数据移动到超出了栈顶的内存单元。想想,如果这个时候这个地址存放的是重要数据或是系统数据,则会引发一连串的异常,这个是我们不愿意看到的。所以,对于栈的操作,我们需要自己注意给一个足够的空间。

原文地址:https://www.cnblogs.com/LearningC/p/1945195.html