基地址寄存器是指在基數位移定址系統中用于存放基地址的寄存器。在執行指令時,通過將基地址寄存器中的基地址與指令地址部的相對地址相加,得出實際地址。
加載
在加載過程中,假設當前正在執行的過程的靜態層號為 i,則當前過程調用記錄前部的區頭地址表共有 i+1 個單元。當需要訪問本過程中說明的簡單變量或形式參數時,只需將 SP 加上該變量的位移地址即可獲得該變量所分配的存儲單元地址。而對于在嵌套深度為 k (k < i) 的過程中說明的變量或形式參數,其存儲單元地址為 (SP + k) + 該變量的位移地址。盡管如此,由于具體的機器指令格式限制,仍需根據具體情況進一步討論這個問題。
機器指令格式是一個與硬件相關的問題。以假想的計算機為例,涉及內存的機器指令的匯編指令格式為 OP R1, d2(R2),其中 R2 是與第二個操作數相關的基地址寄存器,d2 是第二個操作數的位移地址。在形成實際地址時,基地址寄存器中的地址與位移地址相加 ((R2) + d2) 得到第二個操作數的地址。通常情況下,機器指令中的位移區域位數較少(如 12 位),這種指令格式的設計目的是為了縮短每條指令的長度。然而,這給編譯程序形成有效的指令帶來了一定的難度。如果指令的位移區域僅占 12 位,則該指令只能訪問相對于基地址的位移在 4095 個單元范圍內的存儲單元。對于超過 4095 個單元的相對地址,該指令無法進行存取。要存取相對于基地址的位移在 4095 個單元之外的存儲單元中的內容,程序必須先修改基地址寄存器中的地址。由此可知,一個過程的數據區從存儲分配的角度看是一個整體,但從具體指令的編址角度看,過程數據區可以劃分為多個相互連接的部分。每個部分的大小與具體機器指令格式有關。為了訪問某個部分內的存儲單元,必須首先將該部分的首地址放入基地址寄存器,然后按照相對于該部分首地址的位移量訪問該存儲單元。
在代碼生成階段,r3 被保留作為一個特殊用途的寄存器。例如,可以指定 r3 作為基地址寄存器。由于硬件特性,r3 還被用來存放轉子指令執行后的下一條指令地址。當程序流程進入一個過程時,運行時刻執行的過程數據區初始化子程序會將該過程數據區的首地址發送到基地址寄存器 r3。也就是說,當過程主體開始執行時,當前過程調用記錄的第 0 塊首地址已經在 r3 中。如果要訪問的存儲單元位于當前過程調用記錄的第 0 塊,則代碼生成程序可以直接使用 r3 和保存在符號表登記項中的位移地址形成指令。否則,必須修改基地址寄存器的值,即將該存儲單元所屬塊的首地址取到基地址寄存器。這項工作可以通過一個名為 CHECKBP 的專用子程序來完成。
運行時刻子程序 CHECKBP 在工作時需要兩個參數:變量所屬過程的嵌套深度和所屬塊號。變量所屬過程的嵌套深度可以從符號表中該標識符所屬的登記項中獲取。變量所屬塊的塊號也可以從保存在符號表登記項的相對地址中計算得出,通過邏輯乘法截取出該相對地址的高位變量,即是所屬塊號。塊號與每塊長度相乘,再加上該過程調用記錄的首地址,就可以得到塊首址:
塊首址 = 過程調用記錄首址 + 塊號 * 塊長度
其中,過程調用記錄首址可以根據變量所屬過程的靜態嵌套深度從當前過程調用記錄的區頭地址表中獲取。
為了減少頻繁調用運行子程序 CHECKBP,應該注意到程序變量訪問的就近原則:程序員在編寫程序時,往往會將一段程序中使用的變量集中在一起進行說明。這就使得在同一段程序中訪問的變量往往集中在同一個塊或者集中在本過程數據區的第 0 塊。由于假想計算機的寄存器已經被分配完畢,可以在運行程序工作區中設置兩個工作單元 SP 和 BP。SP 存放當前正在執行的過程的調用記錄的首地址,BP 存放當前訪問變量所屬數據塊的首地址。運行子程序 CHECKBP 并不會將變量所屬塊的首地址直接發送到 r3,而是將其地址發送到運行時刻的工作單元 BP。運行時刻子程序 CHECKBP 的代碼編寫工作對于讀者來說并不困難。
為了了解運行時刻 r3、SP 和 BP 的情況,在代碼生成程序中設置了三個工作變量 X、Y 和 Z。X、Y 和 Z 各有兩個域:levelno 和 blockno,分別記錄了運行時刻 r3、SP 和 BP 中地址對應的過程嵌套深度和塊號。進入過程時,運行時刻的過程數據區初始化子程序將當前過程調用記錄的首地址發送到 r3、SP 和 BP。相應的代碼生成程序動作必須將此過程的嵌套深度和第 0 塊標記 0 發送給變量 X、Y 和 Z。之后,每當代碼生成程序要生成訪問運行棧存儲單元的指令時,都必須檢查所要訪問的變量的所屬塊首址是否已經在寄存器 r3 中。如果該地址不在 r3 中,而在工作單元 BP(或工作單元 SP)中,則生成將 BP 值發送到 r3 的指令(或將 SP 值發送到 r3 的指令)。否則,代碼生成程序生成轉向運行時刻子程序 CHECKBP 的轉子指令,以便將所屬塊的首地址取到工作單元 BP,然后再生成將 BP 值發送到 r3 的指令。這些工作可以由子程序 CHECKr3 完成,讀者不難編寫該子程序的代碼。需要注意的是,與 REGVALUE 工作區及 REGSTATE 工作區類似,代碼生成程序的工作變量 X、Y 和 z 必須正確反映運行時刻 r3、SP 和 BP 中地址對應的過程嵌套深度和塊號。
設定
基地址寄存器的設定是在程序中完成的。基地址寄存器的設定方法有兩種,下面以 12 號寄存器為例進行說明:
示例一
```
BEGIN1 START
XXXX USING*, 12
SAVE(14, 12)
LR12, 15
在此示例中,15 號寄存器包含程序的起始地址(即 XXXX)。將 15 號寄存器的內容復制到 12 號寄存器,使基地址寄存器 12 將 XXXX 作為基地址放置。
示例二
```
BEGIN2 START
SAVE(14, 12)
USING*, 12
YYYY BALR 12
在這個例子中,BALR 指令將下一條指令的地址存儲在 12 號寄存器中,而 USING 指令指示匯編程序以當前值為基礎地址進行匯編。因此,基地址寄存器 12 將 YYYY 作為基地址放置。但需要注意的是,在此處不能將 BALR 和 USING 指令的位置顛倒,否則會出現錯誤。
參考資料 >
基于基地址寄存器映射的數據高速緩存設計研究.知網空間.2024-09-16
寄存器.博客園.2024-09-16
基地址.知網空間.2024-09-16