Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 有多少叫做堆栈的东西?_Assembly_Data Structures_X86 - Fatal编程技术网

Assembly 有多少叫做堆栈的东西?

Assembly 有多少叫做堆栈的东西?,assembly,data-structures,x86,Assembly,Data Structures,X86,有多少不同的东西被称为“堆栈”,它们是如何相互关联的?如果有人说“堆栈”,我可以合理地假设他们是指其中一个,或者我只能从上下文中理解它吗 但首先,我想概述一下我在这一点上的理解 在编程中似乎有很多模糊相关的东西都被称为“堆栈”、“堆栈”或类似的东西。除了数据结构之外,我甚至不确定这个术语指的是相同的东西还是不同的东西 基于此,“堆栈”似乎甚至不是一个堆栈数据结构。虽然您只将内容放在它上面,但是您可以访问堆栈中的任何元素,而不必弹出它前面的所有元素。除非我完全误解了数据结构。在阅读本文之前,使用堆

有多少不同的东西被称为“堆栈”,它们是如何相互关联的?如果有人说“堆栈”,我可以合理地假设他们是指其中一个,或者我只能从上下文中理解它吗

但首先,我想概述一下我在这一点上的理解

在编程中似乎有很多模糊相关的东西都被称为“堆栈”、“堆栈”或类似的东西。除了数据结构之外,我甚至不确定这个术语指的是相同的东西还是不同的东西

基于此,“堆栈”似乎甚至不是一个堆栈数据结构。虽然您只将内容放在它上面,但是您可以访问堆栈中的任何元素,而不必弹出它前面的所有元素。除非我完全误解了数据结构。在阅读本文之前,使用堆栈作为变量的数据结构的想法似乎是一个非常糟糕的决定

然后是“堆栈”、调用堆栈和硬件堆栈的问题。我认为硬件堆栈就是调用堆栈,因为您可以将指令放入其中(?),但它不可能也是存储固定大小变量的地方。还是这样?为什么还要在硬件中实现堆栈?我认为变量存储在RAM中,而不是处理器的内存中。或者调用堆栈语言是特定的,因此不是硬件

然后是堆栈框架,除了数据结构之外,它似乎是所有堆栈的通用内容

我不知道如何正确地用谷歌搜索,因为我不确定人们是否在谈论同一件事。我越想理解,就越感到困惑;DR
当我们允许程序调用子例程时,我们需要跟踪调用堆栈(如下所述)。这可以通过多种方式实现,仅受您的创造力的限制,但最简单和最快的方式是指针,它在每次推/弹出某个对象时递增或递减。由于这很容易实现和使用,CPU可以提供删除样板代码的指令和寄存器(并且可以进行优化)。这就是硬件堆栈


对堆栈结构的需要 堆栈是支持后进先出模式的任何结构

CPU本身不需要提供对堆栈的支持(例如,MIPS不需要这样做),但最终还是会使用它

为了理解为什么,只需简单地考虑<强>调用子程序< /强>。 调用子程序时,我们需要记住它的返回地址。
即使CPU将地址存储在寄存器中,比如$ra,问题是被调用方可能需要调用另一个子例程本身
因此,我们需要先节省$ra,然后再打新电话。
同样,这个新的被叫方可能需要再打一次电话,问题可能会重复无限次

如果你仔细想想,你会意识到:

  • 我们需要记住每个回信地址和他们的订单
  • 返回时,我们将从最后一个地址到第一个地址使用这些地址 这是后进先出行为,我们需要一个堆栈,因此名为调用堆栈


    实现调用堆栈 堆栈的实际实现方式由体系结构定义,如果CPU是通用的,则不太可能使用某种形式的内部、不可访问的内存。我们已经可以访问RAM了,为什么不使用它呢?这样我们就不会对递归的深度施加内部限制

    在组装过程中,一切都是由它的用途构成的。
    我们不需要复杂的元数据来实现堆栈,只需要一个简单的指针
    这取决于程序员,确保它的弹出时间不会超过推送的时间,或者确保新推送的元素不会覆盖某些内容

    大多数汇编程序员最终使用寄存器来跟踪堆栈的头部。
    由于这是一种普遍实现的技术,CISC CPU有专用的寄存器和指令来管理堆栈

  • 可以使用隐式堆栈指针在堆栈上推/弹出操作数
  • 调用将使用隐式堆栈指针在堆栈上推送返回地址
  • 返回将使用隐式堆栈指针在堆栈上弹出返回地址(并跳转到它)
  • 如果要使用该名称,这是硬件堆栈

    您没有那么大的自由选择一个实现,因为您的程序通常不是在裸机上独立运行的,所以您需要坚持ABI,并指定堆栈的实现方式

    不是那么简单 汇编编程就像量子物理学,是程序员(观察者)决定事物的本质

    由于程序可以自由访问其RAM,因此无需使用专用指令即可重新实现上述所有堆栈操作。
    如果程序员可以访问堆栈指针(应该可以,否则我们将无法首先设置堆栈),那么我们可以将其用作基本指针,并在堆栈结构上欺骗访问不在顶部的元素

    这是普通的汇编编程。一切都是由使用来定义的,而不是由固定的规则来定义的

    注意我们不能删除不在顶部的元素,因为定义堆栈的唯一东西是它的头指针,堆栈的每个属性都是由该指针定义的。
    包括它的大小

    堆栈的其他用途 一个统一的约定是使用堆栈还存储子例程参数(如果我们已经填充了所有寄存器)和局部变量

    这是由于堆栈的一个非常有趣的属性:很容易在堆栈上分配/释放内存。
    只需来回移动指针。
    假定为t