我知道暫存器用作 CPU 訪問資料以執行指令的存盤單元。這些指令的匯編語言類似于 ADD R2, R1, R3,本質上是要求我們在 R1 和 R3 中添加內容并將其放入 R2。我的問題是,資料如何進入暫存器 R1 和 R3,以便 CPU 可以使用這些值來計算結果并將結果存盤在 R2 中?如果所有暫存器都滿了,是否使用類似于從快取中清除資料的 LRU 方法將資料從暫存器中清除到主存盤器?
uj5u.com熱心網友回復:
值使用機器代碼指令進出暫存器;機器代碼指令可以:
- 將程式中的常量輸入暫存器或記憶體
- 這些通常稱為立即加載或移動
- 將用戶輸入(如擊鍵)輸入暫存器或記憶體
- 一些處理器有輸入指令,另一些從記憶體映射 I/O 加載
- 從記憶體中加載資料,長壽命變數和資料結構所在的位置
- 將暫存器值發送到記憶體
- 更新資料結構和其他長期存在的變數
- 將資料發送到輸出設備(如控制臺)
- 給定現有值計算新值
如果所有暫存器都滿了
這在某種程度上取決于您所說的完整。從某種意義上說,暫存器始終保存值,CPU中沒有空閑/忙碌架構指定暫存器的概念(以浮點和向量暫存器的一些深層概念為模,以及 OoO 處理器的內部實作細節和暫存器重命名)。您的硬碟驅動器也是如此。它正好有 N GB 的存盤空間,就硬體而言,這個數字永遠不會增長或縮小。
如果所有暫存器都滿了,是否使用類似于從快取中清除資料的 LRU 方法將資料從暫存器中清除到主存盤器?
是的,但幾乎 100% 在程式控制下:程式知道我們演算法中的哪些邏輯變數在哪些 CPU 暫存器中(以及其他在哪些記憶體位置),因此有一個演算法可以轉換為具有足夠暫存器的程式集(留下一些未使用的)并且還想要比可用的更多的暫存器。當這種情況發生時(希望超過可用的),編譯器撰寫者和匯編程式員只需轉向記憶體溢位,撰寫機器代碼指令以根據需要來回傳輸資料。不重要的東西可能會存在于記憶體中,并且訪問時間會變慢,從而可以根據需要使用 CPU 暫存器。
(在硬碟驅動器的類比中,所有位始終存在,但并不總是有意義的使用。)
需要明確的是,硬體有許多 LRU 演算法,但這些通常圍繞快取架構,包括 L1、L2 和 TLB。
uj5u.com熱心網友回復:
通用暫存器在概念上與編程語言中的變數非常相似
R1 = 3
R3 = 5
R2 = R1 R3
如何將這些值放入暫存器取決于架構和值。一些指令集具有可變長度指令,可以支持任何可能的值
mov r1,0x12345678
別人可以加載半個暫存器
lui r1,0x12340000
對于真正的處理器來說語法不正確,但是 ISA 將允許控制上半部分,然后您將使用
ori r1,0x5678
最終結果是 r1 = 0x12345678
另一種解決方案是從附近的位置加載
ldr r1,hello
...
hello: .word 0x12345678
這將使用 pc 相對尋址,匯編器會在生成指令時為您進行數學運算,但例如,實際指令類似于從記憶體中的 pc 16 地址加載到暫存器 r1 中。
暫存器是離散的,它們的數量是固定的,它們沒有被快取或先進先出或類似的東西。
從程式員或編譯器的角度來看,如果您只有 8 個暫存器,并且您管理的資料項、變數、地址等超過 8 個,并且您使用的架構要求您使用暫存器一切,那么您通常會使用堆疊來臨時存盤變數。
r1 = 0x12345678 (variable hello)
r2 = 0x55443366 (variable world)
...
I need another variable as the programmer I decide that I can live with out hello for a while
push {r1}
r1 = r2 r3 (variable foo)
str r1,[r4] (the computed value was generated to store in memory)
foo is no longer neaded, but I need hello back
pop {r1}
采用高級語言并生成低級語言(通常是匯編語言或機器代碼)的編譯器將通過函式跟蹤變數并選擇何時使用哪些暫存器。一個特定的暫存器可能在一個函式的執行程序中可能保存幾個變數或地址或其他資料......顯然一次只有一件事。我們會像人類一樣用手做同樣的事情,但要根據演算法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/424433.html
