跳转到内容

调用堆栈

本页使用了标题或全文手工转换
维基百科,自由的百科全书

调用堆栈(英语:Call stack,中国大陆称调用堆栈,台湾称呼叫堆叠)别称有:执行栈(execution stack)、控制栈(control stack)、运行时栈(run-time stack)与机器栈(machine stack),是电脑科学中存储有关正在执行的子程序的消息的。英文有时直接简称“”(the stack),但栈中不一定仅存储子程序消息。几乎所有计算机程序都依赖于调用堆栈,而高级语言一般将调用堆栈的细节隐藏至后台。

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

功能

[编辑]

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

  • 本地变量:子程序的变量可以存入调用堆栈,这样可以达到不同子程序间变量分离开的作用。
  • 参数传递:如果寄存器不足以容纳子程序的参数,可以在调用堆栈上存入参数。
  • 环境传递:有些语言(如PascalAda)支持“多层子程序”,即子程序中可以利用主程序的本地变量。这些变量可以通过调用堆栈传入子程序。

实例

[编辑]

汇编语言

[编辑]

以下MIPS汇编语言程序计算,并将结果存至寄存器s0

main:
    li      $a0, 3
    li      $a1, 4
    jal     sumsq
    move    $s0, $v0
    j       mainend
sumsq:
    addi    $sp, $sp, -4        # 在堆疊上分配空間
    sw      $ra, 0($sp)         # 將sumsq的返回位址存入堆疊中
    jal     square
    move    $t0, $v0
    move    $a0, $a1
    jal     square
    add     $v0, $v0, $t0
    lw      $ra, 0($sp)         # 從堆疊中取回sumsq的返回位址
    addi    $sp, $sp, 4         # 釋出堆疊上分配的空間
    jr      $ra
square:
    mult    $a0, $a0
    mflo    $v0
    jr      $ra
mainend:

这里,主程序(main)调用“sumsq”子程序并将返回地址存入寄存器ra,但是“sumsq”子程序需要调用“square”子程序。为保证sumsq的返回地址不被重写,这个地址被存储在栈中。在square子程序返回后,sumsq再从栈中取回其自身的返回地址。

安全性

[编辑]

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

参见

[编辑]
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy