要對(duì)過程提供機(jī)器級(jí)支持,需要實(shí)現(xiàn)三個(gè)動(dòng)作機(jī)制,現(xiàn)在假設(shè)過程P調(diào)用過程Q,Q執(zhí)行后返回到P:
屏幕快照 2017-09-30 下午3.13.07.png
3.7.1 運(yùn)行時(shí)棧
- 棧用來(lái)傳遞參數(shù)、存儲(chǔ)返回信息、保存寄存器以及局部存儲(chǔ)。
- 當(dāng)過程P調(diào)用過程Q時(shí),會(huì)把返回地址壓入棧內(nèi),指明當(dāng)Q返回時(shí),要從P的哪個(gè)位置繼續(xù)執(zhí)行。
- 大多數(shù)過程的棧幀都是定長(zhǎng)的,在過程的開始就分配好了,但是有些過程需要變長(zhǎng)的幀。
-
通過寄存器,過程P可以傳遞最多6個(gè)整數(shù)值(指針和整數(shù)),但是如果Q需要更多的參數(shù),P可以在調(diào)用Q之前在自己的棧幀里存儲(chǔ)好這些參數(shù)。
屏幕快照 2017-09-30 下午3.16.45.png
3.7.2 轉(zhuǎn)移控制
關(guān)鍵點(diǎn)就是調(diào)用call指令時(shí),會(huì)把父過程繼續(xù)執(zhí)行的地址壓入棧內(nèi),這樣在子過程調(diào)用完成后,會(huì)彈出棧頂,程序計(jì)數(shù)器PC更新為彈出的棧頂值,程序流轉(zhuǎn)回正確的父過程執(zhí)行位置。
屏幕快照 2017-09-30 下午3.26.54.png
3.7.3 數(shù)據(jù)傳送
- x86-64中,大部分過程間的數(shù)據(jù)傳送是通過寄存器實(shí)現(xiàn)的,比如常見的%rdi、%rsi,而返回值可以通過訪問寄存器%rax。
-
通過寄存器最多可以傳遞6個(gè)參數(shù),寄存器使用有特殊順序,并且使用的名字跟傳遞的參數(shù)大小也有關(guān)系。
屏幕快照 2017-09-30 下午3.48.25.png - 如果一個(gè)函數(shù)有大于6個(gè)整型參數(shù),超過6個(gè)的部分要通過棧來(lái)傳遞。通過棧傳遞參數(shù),所有的參數(shù)大小都向8的整數(shù)倍對(duì)齊。參數(shù)到位以后,再調(diào)用call指令進(jìn)行控制轉(zhuǎn)移。
3.7.4 棧上的局部存儲(chǔ)
有些時(shí)候,局部數(shù)據(jù)必須存放在內(nèi)存中,常見情況如下:
屏幕快照 2017-09-30 下午3.56.50.png
3.7.5 寄存器中的局部存儲(chǔ)空間
- 寄存器是唯一被所有過程共享的資源。
- 寄存器%rbx、%rbp、%r12-%r15被劃分為被調(diào)用者保存寄存器。
-
過程P調(diào)用過程Q,為了保證P的一些寄存器的值不被Q覆蓋,調(diào)用之前必須把這些寄存器內(nèi)的值入棧保存起來(lái),然后在Q執(zhí)行完返回后,把這些值恢復(fù)到寄存器內(nèi)
屏幕快照 2017-09-30 下午4.14.13.png
3.7.6 遞歸過程
遞歸調(diào)用一個(gè)函數(shù)本身和調(diào)用其他函數(shù)是一樣的