VM - virtual machine
虛擬機可分為兩種:基於堆棧的(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 。
基於寄存器的虛擬機需要用寄存器來保存中間結果、變量等,而基於堆棧的虛擬機使用堆棧即可。例如,針對同一條指令:Add,基於堆棧的處理器的首先從堆棧裏Pop兩個數,然後將兩數相加,再把和Push到堆棧,Add指令只佔用1個字節,而基於寄存器的處理器的對應指令為AddR1,R2,113,Add指令至少要佔用4個字節。通過以上比較可以看出,基於堆棧的體系架構實現較為簡單,但其運行效率不如基於寄存器的,而基於寄存器的體系結構在編譯後的代碼結構上又不如基於堆棧的簡潔。對於同一個程序,為基於堆棧的機器編譯出來的版本要比為基於寄存器的機器編譯出來的版本小好幾倍。(為什麼反而比較小呢,我現在忘記原因了
基於堆棧的指令集能夠讓字節碼更緊湊,可以提高Cache的利用率,而且實現起來也比基於寄存器的機器要簡單。而基於寄存器的虛擬機雖然代碼大小有所增加,但是帶來的性能提升更加突出。