> 教育经验 > 什么是执行栈介绍

什么是执行栈介绍

什么是执行栈介绍

执行栈是计算机科学中存储有关正在运行的子程序的消息的栈。有时称控制栈(control stack)、运行时栈(run-time stack)和调用栈,但栈中不一定仅存储子程序消息。几乎所有计算机程序都依赖于执行栈,然而高级语言一般将调用栈的细节隐藏至后台。

执行栈简介

执行栈是计算机科学中存储有关正在运行的子程序的消息的栈。经常被用于存放子程序的返回地址。在调用任何子程序时,主程序都必须暂存子程序运行完毕后应该返回到的地址。因此,如果被调用的子程序还要调用其他的子程序,其自身的返回地址就必须存入执行栈,在其自身运行完毕后再行取回。在递归程序中,每一层次递归都必须在执行栈上增加一条地址,因此如果程序出现无限递归(或仅仅是过多的递归层次),执行栈就会产生栈溢出。

执行栈栈

栈(stack)是限定仅在表尾进行插入或删除操作的线性表。因此,对栈来说,表尾端有其特殊含义,称为栈顶(top),相应地,表头端称为栈底(bottom)。

栈也可以是指计算机内存中由程序指定的一个后进先出(LIFO)存储区或CPU内部的一个LIFO寄存器组。前者称软栈,后者称硬栈。软栈的一端是固定的,另一端是浮动的,浮动的一端称为栈顶。所有信息的存入和取出都只能在栈顶进行,而且是在堆栈指示字寄存器的配合下,按LIFO原则工作的。硬栈栈顶一端是固定的,压入的数据项占据栈顶,栈中原有的数据项都依次向栈底方向移动;弹出数据时,最后进栈的数据项先被弹出,下面各级数据项依次向栈顶方向移动。软栈和硬栈功能均相同,主要作为LIFO缓冲存储器,用于中断处理、子程序嵌套及暂存数据。在程序中断时,堆栈(自动)保存程序计数器、状态寄存器及工作寄存器的内容,并在中断结束后把这些现场内容恢复到相应的寄存器中。

执行栈功能

执行栈的主要功能是存放返回地址。除此之外,调用栈还用于存放:

本地变量:子程序的变量可以存入调用栈,这样可以达到不同子程序间变量分离开的作用。

参数传递:如果寄存器不足以容纳子程序的参数,可以在调用栈上存入参数。

环境传递:有些语言(如Pascal与Ada)支持“多层子程序”,即子程序中可以利用主程序的本地变量。这些变量可以通过调用栈传入子程序。

在较底层语言(如汇编语言与C语言中),程控消息与数据可能一同被存入调用栈中,因此造成安全隐患,可能允许恶意程序通过栈缓冲区溢出(stack buffer overflow)来获取程序的控制权。

执行栈堆栈溢出

堆栈溢出(英语:stack overflow)在计算机科学中是指使用过多的内存时导致调用堆栈产生的溢出。堆栈溢出的产生是由于过多的函数调用,导致调用堆栈无法容纳这些调用的返回地址,一般在递归中产生。堆栈溢出很可能由无限递归(Infinite recursion)产生,但也可能仅仅是过多的堆栈层级。

堆栈溢出在内核设计中尤其危险,因此很多入门内核设计教程建议用户不要尝试使用递归程序;而是基于安全和性能考量,改用循环处理问题。

执行栈递归

是计算机问题求解的一种算法.是一种处理过程,这种过程的某一步要用到它自身的上一步(或上几步)的结果。一个直接或间接地调用自己的过程称为递归过程.在本过程中出现调用本过程自身的过程称为直接递归过程;若过程P包含着对另一过程Q的引用,而Q又直接或间接地引用P,则称P为间接递归过程。一个使用函数自身给出定义的函数称为递归函数。在数学定义和计算机算法中,递归技术是一种特别有力的工具。递归函数或递归过程的应用往往使函数的定义和算法的描述比使用非递归方法更简明。

执行栈递归过程

在程序设计中,使一个过程本身用 作一个子过程,这一做法往往是很方便的。如果过程这样做,就称为递归的。在处置符号表达式中,递归 过程尤为自然,因为这样的程序结构与数据结构相匹配。至于程序设计语言,递归过程是十分自然的;在语言的定义中要求一个专门的语句来禁止它们。 但是,它们的实现就要求编译一个特种的目标代码, 象Fortran这样的早期程序设计语言中是不容许的。 问题在于:程序中的变量与机器中的存储单元相对应,当程序被它本身调用时,它将使用这些相同的存储单元,改写它们原先的内容。所以,递归程序使用 一个称为栈的数据结构,用来把必须保存的寄存器内容存储起来。这一存储可在进入子例程之前由调用程序来完成,或者可在使用这些寄存器之前由子例程来完成,后者较常用。

在寄存器已保存在栈上之后,进入栈的索引增大到存储的寄存器数,因而栈上其后的保存将使用新的寄器。当存在子例程时,保存的寄存器的内容从栈恢复到它们原先的值,栈指针按其原先增加的量减少。这项工作是根据如何存入的而通过相应的 调用程序或子例程来完成的。另一种方法是使用栈作所有的暂时寄存器。在这种情况下,无需把数据传来传去,只需在子例程进入与离开时改变栈指针。但是,这种方法对某些机器可能会用尽它的索引能力, 而这能力也是其他用途所需要的。递归程序可用任 何程序设计语言通过显式地把保存和恢复进行程序 设计的方法来编写。在常规基础上使用递归子例程的第一个语言是 Newell、Shaw和Simon的IPL语言。用表当作栈使 用,保存与恢复显然由程序员完成。第一个提供用于 递归的自动机构是Lisp。Algol和其后继者Pascal和 Ada也容许递归,APL、PL/I、C和Snobol等其他语 言也一样。许多计算机有处置栈的专用指令(例如,Digital Equipment DEC-10的PUSH和POP指令)。其他机器,例如Burroughs B5000和其后继者,具有直接使用硬件栈的指令。这些专用的设施对于递归程序设计的效率有适度的增加。