問一個關於寄存器與棧的問題?

今天得知曾經的計算機只有一個供算數運算指令使用的寄存器, 學編譯原理時也有隻由一個棧組成的棧式計算機. 因為同一天接受了這兩個概念, 所以很好奇這兩者有沒有什麼聯繫, 畢竟看到的指令和功能(用來運算))也挺相似的, 比如`Add`. 謝謝


因為這樣抽象最簡單,不然一上來就要你做寄存器分配,搞動態規劃,時間就都花在奇怪的地方上面了。CPU裡面的一大堆寄存器,在經過編譯器的分配之後,其實就等於不同時刻的若干個棧頂元素的一個view,如果只是從「如何生成一個能運行的代碼」的角度來看的話,其實也沒有什麼太大的區別。

然後你在任意時刻,你都能把每一個寄存器map到(實際上不存在的抽象的)堆棧的幾個棧頂元素里,但是不同的map的方法自然就會導致你生成的代碼不一樣(特別是x86/x64系列指令,寄存器的功能還不一樣,分配程序寫起來雞巴那麼長)。假設你能夠給出代碼的運行時間的一個估計的話,那麼如何在不改變表達式結構的前提下,求一個最好的寄存器分配的方法,其實就跟求最短路徑是差不多的。


關於你說的

曾經的計算機只有一個供算數運算指令使用的寄存器

可以給你舉個例子,增加點直觀理解。

比如多年前我用過的一款 8 位學習機 COMX PC-1,是以 RCA CDP1802 晶元作為 CPU 的計算機。CDP1802 是 8 位微處理器,只有一個 8 位累加器 D 和一個 1 位進位標誌寄存器 DF 可用來進行算術運算。對於二元算術運算,一個操作數必須在累加器 D 中,另一個必須在棧頂指示的內存中。雖然它有 16 個 16 位通用寄存器 R0 ~ RF,但是是不能直接進行算術運算的,只能存數。

假設 R8 和 R9 兩個寄存器中分別保存了 16 位數 0x1234 和 0xABCD,你希望計算這兩個數的和,保存到寄存器 R7 中,那麼機器指令是這樣的:

98 GHI R8 ; 取 R8 的高 8 位放入累加器
73 STXD ; 將累加器中的值入棧
88 GLO R8 ; 取 R8 的低 8 位放入累加器
73 STXD ; 將累加器中的值入棧
89 GLO R9 ; 取 R9 的低 8 位放入累加器
60 IRX ; 棧指針加 1,暴露棧頂。此時棧頂為 R8 低 8 位值
74 ADC ; 累加器的值加棧頂的值及進位,結果存入累加器,更新進位標誌
A7 PLO R7 ; 將累加器的值存為 R7 低 8 位
99 GHI R9 ; 取 R9 的高 8 位放入累加器
60 IRX ; 棧指針加 1。此時棧頂為 R8 高 8 位值
74 ADC ; 累加器的值加棧頂的值及進位,結果存入累加器,更新進位標誌
B7 PHI R7 ; 將累加器的值存為 R7 高 8 位


https://www.zhihu.com/question/35777031/answer/64575683?utm_source=wechat_sessionutm_medium=socialfrom=singlemessage

感覺題主可以看看這個?


沒什麼關係,用寄存器算數據,用棧存數據


推薦閱讀:

剛入門編程的人有必要學習數據結構嗎?
C語言初學者進階學習數據結構與演算法路線?方法?
為什麼大多數編程語言的內建抽象數據類型沒有圖?
自學離散數學,用哪一本書比較好?我自己已經有很多本好難選?
如何設計數據結構和演算法,計算並存儲六度好友關係?

TAG:操作系統 | 數據結構 | 編譯原理 | 計算機組成原理 |