• 汇编笔记 之二 栈


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

                什么是栈呢,栈并非真的存在,只是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

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

  • 相关阅读:
    python datetime,字符串,时间戳相互转换
    python在linux环境读取access数据库mdb文件
    ruby 随机字符串rand方法避坑
    gin 页面重定向
    go语言 goquery爬虫
    Rails项目防止时序攻击
    Authorization With Pundit
    Rails/ActiveRecord order by Array
    java线程池
    Java安全API
  • 原文地址:https://www.cnblogs.com/LearningC/p/1945195.html
Copyright © 2020-2023  润新知