官术网_书友最值得收藏!

1.5 函數的調用機制

接下來,我們繼續介紹程序的流程。哪怕是高級語言編寫的程序,函數很多高級編程語言都采用類似于y=f (x)這樣的數學函數的語法來記述編寫處理。我們知道,該數學函數的意思是將x這個值通過f處理后得到數值y。如果套用函數的語法,x就是參數,y就是返回值,執行函數的功能就是函數調用。調用處理也是通過把程序計數器的值設定成函數的存儲地址來實現的。不過,這和條件分支、循環的機制有所不同,因為單純的跳轉指令無法實現函數的調用。函數的調用需要在完成函數內部的處理后,處理流程再返回到函數調用點(函數調用指令的下一個地址)。因此,如果只是跳轉到函數的入口地址,處理流程就不知道應該返回至哪里了。

圖1-7是給變量a和b分別代入123和456后,將其賦值給參數(parameter)來調用MyFunc函數的C語言程序。圖中的地址是將C語言編譯成機器語言后運行時的地址。由于1行C語言程序在編譯后通常會變成多行的機器語言,所以圖中的地址是離散的。

圖1-7 程序調用函數示例(這里直接展示了C語言的源代碼,實際上各地址存儲的應該是變換成機器語言后的程序)

此外,通過跳轉指令把程序計數器的值設定成0260也可實現調用MyFunc函數。函數的調用原點(0132地址)和被調用函數(0260地址)之間的數據傳遞,可以通過內存或寄存器來實現。不過,當函數處理進行到最后的0354地址時,我們知道應該將程序計數器的值設定成函數調用后要執行的0154地址,但實際上這一操作根本無法實現。那么,怎么辦才好呢?

機器語言的call指令和return指令能夠解決這個問題。建議大家把二者結合起來來記憶。函數調用使用的是call指令,而不是跳轉指令。在將函數的入口地址設定到程序計數器之前,call指令會把調用函數后要執行的指令地址存儲在名為棧棧(stack)本來是“干草等堆積如山”的意思。在程序領域中,通常使用該詞來表示不斷地存儲各種數據的內存區域。函數調用后之所以能正確地返回調用前的地址,就是棧的功勞。關于棧,我們會在第4章進行詳細說明。的主存內。函數處理完畢后,再通過函數的出口來執行return命令。return命令的功能是把保存在棧中的地址設定到程序計數器中。如圖1-7所示,MyFunc函數被調用之前,0154地址保存在棧中。MyFunc函數的處理完畢后,棧中的0154地址就會被讀取出來,然后再被設定到程序計數器中(圖1-8)。

圖1-8 函數調用中程序計數器和棧的職能

在編譯高級編程語言的程序后,函數調用的處理會轉換成call指令,函數結束的處理則會轉換成return指令。這樣一來,程序的運行也就變得非常流暢。

主站蜘蛛池模板: 育儿| 通化县| 北碚区| 兴文县| 奈曼旗| 溆浦县| 马关县| 沅陵县| 米泉市| 胶南市| 五家渠市| 静宁县| 邯郸市| 津南区| 甘泉县| 广安市| 包头市| 赤水市| 富源县| 益阳市| 淄博市| 穆棱市| 泰宁县| 榆树市| 科技| 稷山县| 图木舒克市| 扬州市| 鲁甸县| 利津县| 平山县| 茂名市| 林甸县| 昭通市| 四会市| 武清区| 合肥市| 纳雍县| 洞头县| 黄梅县| 邵阳县|