报头中的偏移量作用_C语言中函数的实现
符號表
C編譯器使用符號表來記錄程序中遇到的變量,類似匯編器中的label表,不過C編譯器中的符號表包括更多信息:名字、類型、已分配的內存地址、變量申明域或作用域等
e.g 程序中有6個變量聲明,編譯器會生成6個表項的符號表,采用偏移量的方式記錄變量在內存中的位置編譯器的符號表變量的空間分配
存放變量內容的內存有兩種區段:全局數據段(global data section)和運行時棧(run-time stack)。全局數據段是內存中存放全局變量的區段,即所有靜態變量所在的地方;運行時棧則是局部變量所在的地方。
在LC-3體系計算機中,R4是一個專用寄存器,存放的是全局數據段的基地址,所以R4可以被看做成一個全局指針。
e.g 全局變量earth偏移量為4,將earth的內容讀入寄存器R3,LC-3指令如下:LDR R3, R4, #4局部變量就會存放在一個被稱作”活動記錄“(activation record)或者”堆棧幀“(stack frame)的內存模板(memory template)中。活動記錄就是一段連續的內存,包含了當前函數中所有的局部變量。每個函數都有自己的活動記錄,當我們調用一個函數的時候,該函數活動記錄的最大地址存放在寄存器R5中,R5被稱為幀指針(frame pointer)。注意,在活動記錄中,變量的排放順序與他們在程序中的聲明順序是相反的。
e.g 變量amount在程序中是最先被聲明的變量,它也是距離幀指針R5最近的變量,訪問變量seconds,LC-3指令如下:LDR R0, R5, #-5LC-3內存中的一個活動記錄當我們調用一個函數的時候,該函數的活動記錄被壓入當前棧,同時R5內容被調整,指向當前棧頂,當該函數結束的時候,控制權被交還給調用者,活動記錄將被彈出當前棧,同時R5的內容也將被修改,指向調用者活動記錄所在位置。整個過程中,寄存器R6始終指向運行時棧的頂部,R6為棧指針。
C語言中,函數調用包括三個步驟:
運行時棧
在函數被調用時,我們需要激活被調用函數,也就是說在函數被執行前,必須要在內存中,為該函數的局部變量分配空間。
每個函數的活動記錄,在其每次被調用的時候,都會被系統在內存中分配一個活動記錄空間。函數返回的時候,則將該活動記錄返還,以供其他函數調用使用,這樣是允許函數的遞歸操作的。其中采用數據結構”棧“來跟蹤函數調用模式。
e.g
int main() { int a; int b;: b = Watt(a); b = Volta(a,b); }int Watt(int a) { int w;: w = Volta(w, 10); return w; }int Volta(int q; int r) { int k; int m;: return k; }上圖是棧在代碼運行的不同時刻的快照,每個陰影區代表一個特定函數的活動記錄,將數據項壓入棧時,棧頂總是向著低的內存地址方向移動。其中R5總是指向當前活動記錄的某個地址(局部變量的起始地址),R6總是指向運行時棧頂。
實現機制
e.g
w = Volta(w, 10);1、調用
通過將兩個參數值壓入運行時棧,向Volta傳遞參數,R6指向運行時棧頂部,每當向棧中壓入一個數據項,首先遞減R6值,然后將數據存入R6指向的地址。在LC-3結構中,C函數的參數,按照它們在函數調用的順序,從右到左依次被壓入棧。
通過JSR指令,把控制權交給Volta
AND R0, R0, #0 ADD R0, R0, #10 ADD R6, R6, #-1 STR R0, R6, #0 LDR R0, R5, #0 ADD R6, R6, #-1 STR R0, R6, #0 JSR Volta2、被調用函數的開始
被調用函數的初始代碼,要完成與調用信息相關的備份操作:
為返回值預留一個內存位置,通過棧指針遞減,將一個內存空間“壓”入棧,在被調用函數返回調用者之前,將返回值填入此內存。
調用者相關的信息的保存,即R7中調用者的返回地址和R5中調用者的幀指針(動態鏈)。
被調用者調整R6的值,在棧空間中為它的局部變量分配足夠的空間,同時設置R5指向這些局部變量的基地址。
Volta: ADD R6, R6, #-1 ADD R6, R6, #-1 STR R7, R6, #0 ADD R6, R6, #-1 STR R5, R6, #0 ADD R5, R6, #-1 ADD R6, R6, #-23、被調用函數的結束
如果存在返回值,則填寫活動記錄的返回值字段。
將局部變量彈出棧
恢復原動態鏈的內容
恢復返回地址
通過RET指令,返回調用者
LDR R0, R5, #0 STR R0, R5, #3 ADD R6, R5, #1 LDR R5, R6, #0 ADD R6, R6, #1 LDR R7, R6, #0 ADD R6, R6, #1 RET4、返回調用函數
將返回值(如果有)出棧
參數出棧
JSR Volta LDR R0, R6, #0 STR R0, R5, #0 ; w = Volta(w, 10); ADD R6, R6, #1 ADD R6, R6, #2總結
以上是生活随笔為你收集整理的报头中的偏移量作用_C语言中函数的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Weblogic 所有BEA错误代码详细
- 下一篇: CSDN 迷你博客错误