嵌入式程序调用函数的内部过程和机制
在嵌入式程序中,當一個函數調用發生時,它的內部機理是什么,執行了哪些步驟?如下所示是一個程序在運行時,它的內存分布狀況。
當一個程序開始運行時,它的代碼被裝入到內存,保存在代碼區,包括主函數和其他函數的代碼。另外,還有三塊內存區域用來存放數據。第一塊是全局變量區域,存放了程序當中的所有全局變量。由于全局變量的個數和大小是已知的,所以這一塊區域所占用的內存大小在開始時即可確定下來,它們被稱為是靜態分配。位于此區域內的變量,它們在程序的整個運行過程當中,都一直存在,只有當整個程序運行結束了, 這一塊內存區域才會被釋放。第二塊區域是棧(stack)區域,它包含了所有的棧幀。所謂的棧幀( stack frame),就是在調用一個函數時,系統會自動地分配一塊內存區域給這個函數,用來保存它的運行上下文、形參和局部變量等信息,這樣的一塊內存區域,就叫做一個棧幀。棧幀是在函數調用時分配的,當函數調用結束之后,相應的棧幀就會被釋放。所以,對于一個函數的局部變量來說,只有當函數調用發生時,系統才會給這個函數的形參和局部變量分配存儲空間;當函數調用結束后,這些局部變量就被釋放掉了。另外,由于棧區域是由系統自動來分配的,用戶并不需要去關心,所以也稱為是自動分配。第三塊區域是堆(heap) 區域,它主要是用作動態分配的內存。
如上圖所示是函數調用的一個例子,它考察的是最簡單的一種情形,即在整個程序當中,只有一個main函數。在這種情況下,當程序開始運行時,它就會被裝入到內存。它的代碼存放在內存的代碼區域。由于在這個程序中定義了一個全局變量z,所以就在內存的全局變量區域分配了一個存儲單元給它,并且把它初始化為0。接下來,系統就要調用主函數main去運行了,當這個函數調用發生時,系統就會在棧中給它分配一塊內存空間,即一個棧幀,用來存放主函數當中所定義的局部變量,即x和y。隨后,程序計數器PC就跳轉到主函數的第一條語句, 開始執行。當main函數執行完后,首先要把它所占用的棧幀釋放掉。對于任何一次函數調用來說,在函數調用結束后,都要把相應的棧幀釋放掉,所以x和y這兩個局部變量所占用的存儲空間就被釋放掉了,不能再訪問了。接下來,由于main函數是一個特殊的函數,當它執行完之后,整個程序也就結束了。
當一次函數調用發生時,它的執行過程可以歸納為以下5個步驟:
-
在內存的棧空間當中為其分配一個棧幀,用來存放該函數的形參變量和局部變量。
-
把實參變量的值復制到相應的形參變量中。
-
控制流轉移到該函數的起始位置。
-
該函數開始執行。
-
當這個函數執行完以后,控制流和返回值返回到函數調用點。
如下圖所示是變量的存儲與作用域的一個例子。
總結
以上是生活随笔為你收集整理的嵌入式程序调用函数的内部过程和机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 单片机I/O控制方式(UART中断和DM
- 下一篇: Python解析照片EXIF信息,获取坐