1. 程式人生 > >於堆疊的(Stack-based ) 和基於暫存器(Register-based) 的虛擬機器區別

於堆疊的(Stack-based ) 和基於暫存器(Register-based) 的虛擬機器區別

轉載:
虛擬機器可分為兩種:基於堆疊的(Stack-based ) 和基於暫存器(Register-based) 的虛擬機器。基於堆疊的虛擬機器也定義了少量的暫存器,基於暫存器的虛擬機器也有堆疊,其區別體現在它們提供的指令集體系結構(ISA ,Instruction Set Architecture) 。ISA 是處理器的一部分,對於編譯器實現者和程式設計師是可見的,ISA 是硬體和軟體之間的介面。基於堆疊的虛擬機器的指令比基於暫存器的指令要小,因為在指令中不需要指定運算元。基於堆疊的虛擬機器使用堆疊來儲存中間結果、變數等,基於暫存器的虛擬機器則支援暫存器的指令操作。基於堆疊的虛擬機器需要用Push 、Pop 來傳送資料,通常,完成同樣的工作,基於暫存器的虛擬機器所採用的指令數比基於堆疊的虛擬機器採用的指令數目少,可以提高執行效率。例如,將語句 C=A+B轉化為中間程式碼,如圖3.3所示。
這裡寫圖片描述


這裡寫圖片描述
堆疊虛擬機器指令很低階,基於暫存器的處理器有更強大的指令功能,而且易於除錯。
基於堆疊的處理器在處理函式呼叫、解決遞迴問題和切換上下文時簡單明快。
採用暫存器架構時,虛擬機器需要經常儲存和恢復暫存器中的內容,還要考慮對運算元的定址問題等,因此,基於堆疊的虛擬機器實現起來更簡單,基於暫存器的虛擬機器能提供更強大的指令集。
大多數虛擬機器是基於堆疊的,如Pascal’s P-machine 、Java 的JVM和微軟的.Net 環境。當前流行的 Lua 指令碼語言,5.0之前的版本也是基於堆疊的,5.0之後改為基於暫存器實現。虛擬機器實現越複雜,解密者也就越難破解,但是其實現成本也高。
基於暫存器的虛擬機器需要用暫存器來儲存中間結果、變數等,而基於堆疊的虛擬機器使用堆疊即可。例如,針對同一條指令:Add,基於堆疊的處理器的首先從堆疊裡Pop兩個數,然後將兩數相加,再把和Push到堆疊,Add指令只佔用1個位元組,而基於暫存器的處理器的對應指令為AddR1,R2,113,Add指令至少要佔用4個位元組。通過以上比較可以看出,基於堆疊的體系架構實現較為簡單,但其執行效率不如基於暫存器的,而基於暫存器的體系結構在編譯後的程式碼結構上又不如基於堆疊的簡潔。對於同一個程式,為基於堆疊的機器編譯出來的版本要比為基於暫存器的機器編譯出來的版本小好幾倍。
基於堆疊的指令集能夠讓位元組碼更緊湊,可以提高Cache的利用率,而且實現起來也比基於暫存器的機器要簡單。而基於暫存器的虛擬機器雖然程式碼大小有所增加,但是帶來的效能提升更加突出