2012-03-21 173 views
7

我在業餘時間學習彙編語言以成爲更好的開發人員。彙編語言 - 堆棧機

我理解基於堆棧的機器和基於寄存器的機器在概念層面上的區別,但我想知道如何實現基於堆棧的機器。如果虛擬機,例如JVM或.NET,在基於寄存器的架構上運行,例如x86或x64,那麼它必須在彙編級別使用寄存器(就我而言)。我顯然在這裏錯過了一些東西。因此我不確定彙編語言的區別。

我已閱讀過這裏的文章例如Stack-based machine depends on a register-based machine?和維基百科上,但我不相信他們直接回答我的問題。

+0

他們*可以*在軟件中模擬它,老的JVM就是這樣做的。通常儘管堆棧機器代碼被編譯爲本地代碼(無論可能的架構如何)。堆棧機器代碼很好,因爲它具有簡潔的編碼,它很容易從AST生成並且相對容易分析。 – harold 2012-03-21 10:24:51

回答

4

那麼它必須在組件級別

使用寄存器

這不是一個要求,處理器有一個CPU堆棧,其行爲很像中介語言中的虛擬堆棧。您可以將指令幾乎一對一地轉換爲cpu指令。當然,基於堆棧的虛擬機很受歡迎的原因之一是,抖動很容易實現。

這樣做的唯一方法就是機器碼不是非常高效。抖動優化器的作用是找到有效使用cpu寄存器的方法,並使代碼更快。

相反的問題出現在基於寄存器的虛擬機中。由於真正的CPU沒有虛擬機的寄存器那麼多,所以要解決這個問題是一個難題。所以抖動必須找到方法來使用堆棧溢出硬件不提供的寄存器。

7

基於堆棧的機器很少在硬件上實現 - 我只聽說過一個這樣的實現,並且從來沒有機會在其中工作。

實際上,堆棧機器是由本機解釋器在基於真正寄存器的處理器上實現的。實質上,理論堆棧機器由真正的基於寄存器的機器模擬。

所以要回答你的問題:雖然堆棧機器的機器代碼沒有寄存器,但執行這些指令的本機解釋器確實有寄存器並且正在使用它們。

問:那麼爲什麼間接? A:可移植性 - 堆棧機器的指令集可以在任何數量的基於寄存器的不同機器上仿真。這意味着,在同一個JVM的應用程序可以有一個解釋,因此,舊的Java口號在任何機器上運行「編寫一次,隨處運行」

+0

你是什麼意思「原生翻譯」。你指的是JIT編譯器(在.NET的情況下)? – w0051977 2012-03-21 10:04:34

+0

「原生解釋器」我的意思是在本地機器上運行的應用程序讀取堆棧機器指令後執行它們。每種類型的機器(和操作系統)都會有不同的「本地解釋器」。在Java的情況下,「本機解釋器」就是JVM。 JIT的情況稍有不同。 – Stormcloud 2012-03-21 10:47:05

+0

僅供參考,JIT是將堆棧機器指令轉換爲本地機器(基於寄存器的指令)的一組等同指令的東西。這是爲了使應用程序的性能接近本機處理器的性能,但同時保持便攜性的優勢。 – Stormcloud 2012-03-21 12:19:06

6

作爲參考,Burroughs B5000Inmos Transputer是堆棧機器。 DEC PDP11有這樣靈活的尋址模式,它可以用作堆棧機器。我認爲Niklaus Wirth's Lilith可能是一個堆棧機器(超過20年前,我的腦海正在滑倒:-)

他們真的沒有任何寄存器名稱/編號的指令找到操作數,因爲他們在堆棧上。

指令可以將即時(常量)值加載到堆棧上,或加載/存儲到內存中。

所以他們是沒有add.w r0, r1, r5add.w eax, [#fe34]。有add.w

所以一個例子(不是在所有準確,這是更復雜的)的彙編序列的可能是

loadstack 0xfe34 -- got fe34 onto stack 
loadstackindirect -- use address on the stack, to load the value at that address 
add.w    -- assumes we already have the other operand on the stack 
        -- result back onto the stack 

要計算並加載在數組中的值,可以使用堆棧因爲可能有沒有索引尋址模式。

因此,指令很小,大量的工作是隱式地使用堆棧和堆棧指針完成的。 IIRC Transputers實際上只有三個值,編譯器(或開發人員)必須確保維護。

XMOS現在出售一個現代的「等值」,並僱用一些相同的人。

自從我編寫Transputer代碼已經有20多年了,所以很抱歉有點含糊。

UCSD Pascal系統使用軟件定義的虛擬機,它是一個堆棧機器。這個想法是爲了創造一些可以移植到新電腦上的東西,但也易於編寫,易於編譯和合理的性能。它的虛擬機被定義爲它自己的Pascal方言。當它被移植到真正的計算機上時,寄存器將被用來保存堆棧指針,並且可能在處理堆棧頂部(通過寄存器)方面有一些獨創性,以獲得合理的性能。