查看“︁呼叫堆疊”︁的源代码
←
呼叫堆疊
跳转到导航
跳转到搜索
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
{{Multiple issues| {{refimprove|time=2011-12-20T05:54:42+00:00}} {{Expand language|1=en|time=2020-07-28T07:49:47+00:00}} }} {{noteTA |G1=IT |1=zh-cn:栈;zh-tw:堆疊 |2=zh-cn:调用堆栈;zh-tw:呼叫堆疊 }} {{地區用詞|cn=调用堆栈|tw=呼叫堆疊|start={{lang-en|Call stack}}|as=稱}}别称有:'''执行栈'''(execution stack)、'''控制栈'''(control stack)、'''运行时栈'''(run-time stack)与'''机器栈'''(machine stack),是[[電腦科學]]中存儲有關正在執行的[[子程式]]的訊息的[[堆疊]]。英文有時直接简称“'''栈'''”(the stack),但堆疊中不一定僅存儲子程式訊息。幾乎所有[[電腦程式]]都依賴於呼叫堆疊,而[[高階語言]]一般將呼叫堆疊的細節隱藏至後台。 呼叫堆疊最經常被用於存放子程式的返回位址。在呼叫任何子程式時,主程式都必須暫存子程式執行完畢後應該返回到的位址。因此,如果被呼叫的子程式還要呼叫其他的子程式,其自身的返回位址就必須存入呼叫堆疊,在其自身執行完畢後再行取回。在[[遞迴]]程式中,每一層次遞迴都必須在呼叫堆疊上增加一條位址,因此如果程式出現無限遞迴(或僅僅是過多的遞迴層次),呼叫堆疊就會產生[[堆疊溢位]]。 ==功能== 呼叫堆疊的主要功能是存放返回位址。除此之外,呼叫堆疊還用於存放: * [[本地變數]]:子程式的變數可以存入呼叫堆疊,這樣可以達到不同子程式間變數分離開的作用。 * [[參數]]傳遞:如果[[暫存器]]不足以容納子程式的參數,可以在呼叫堆疊上存入參數。 * 環境傳遞:有些語言(如[[Pascal_(程式語言)|Pascal]]與[[Ada]])支援「多層子程式」,即子程式中可以利用主程式的本地變數。這些變數可以通過呼叫堆疊傳入子程式。 ==實例== ===組合語言=== 以下[[MIPS架構|MIPS]][[組合語言]]程式計算<math>3^2+4^2</math>,並將結果存至[[暫存器]]<code>s0</code>。 <syntaxhighlight lang="asm"> 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: </syntaxhighlight> 這裡,主程式(main)呼叫「sumsq」子程式並將返回位址存入暫存器<code>ra</code>,但是「sumsq」子程式需要呼叫「square」子程式。為保證sumsq的返回位址不被重寫,這個位址被存儲在堆疊中。在square子程式返回後,sumsq再從堆疊中取回其自身的返回位址。 ==安全性== 在較底層語言(如[[組合語言]]與[[C語言]]中),程式控制訊息與資料可能一同被存入呼叫堆疊中,因此造成安全隱患,可能允許惡意程式通過[[栈缓冲区溢出]](stack buffer overflow)來獲取程式的控制權。 ==參見== * [[記憶體管理]] * [[调用约定]] * [[堆疊溢位]] {{x86汇编话题}} [[Category:计算机编程]]
该页面使用的模板:
Template:Multiple issues
(
查看源代码
)
Template:NoteTA
(
查看源代码
)
Template:X86汇编话题
(
查看源代码
)
Template:地區用詞
(
查看源代码
)
返回
呼叫堆疊
。
导航菜单
个人工具
登录
命名空间
页面
讨论
不转换
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
工具
链入页面
相关更改
页面信息