計算機要素--第七章 虛擬機I:堆棧運算

計算機系統要素,從零開始構建現代計算機(nand2tetris)
如果完成了本書所有的項目 你將會獲得以下成就

  • 構建出一臺計算機(在模擬器上運行)
  • 實現一門語言和相應的語言標準庫
  • 實現一個簡單的編譯器

而且,這本書的門檻非常低,只要你能熟練運用一門編程語言即可。本課程綜合了數字電路,計算機組成原理,計算機體系架構,操作系統,編譯原理,數據結構等的主要內容,搭建了計算機平臺的構建的框架,並未深入細節,如果需要了解細節,可由本書作爲主線,逐步完善的知識體系。

QQ交流羣(含資料):289682057
課程連接
項目地址Github


本章要實現的內容

  • 算術邏輯命令
  • 內存訪問命令

詳細內容

下面是一些主要內容

  • 編譯器採用兩層轉換模型進行構建,首先高級語言將被翻譯成中間代碼,然後中間代碼被轉換成機器語言。這種劃分方式有利於減少高級語言和機器語言之間的依賴性。
  • 將高級語言翻譯成中間代碼的程序可以稱爲編譯器前端程序,而將中間代碼翻譯成機器語言的程序可以稱爲編譯器後端程序。比如JAVA,JAVA的源碼經翻譯後形成字節碼文件,字節碼文件是運行在java虛擬機上的,而字節碼文件經翻譯後得到機器語言,機器語言運行在硬件平臺上。中間代碼運行在虛擬機上,機器語言運行在硬件上。
  • 在這個項目中,虛擬機語言共包含4種類型的命令:算術命令,內存訪問命令,程序流程控制命令和子程序調用命令。
  • 編譯器的後端程序負責的是將中間代碼翻譯成機器語言,所以它與硬件平臺的關係性非常大,如果我們需要運行在不同的硬件平臺上,那麼機器語言就會發生變化,因此後算程序就需要改變,而前端程序不需要改變,因此虛擬機可以使語言很方便的進行跨平臺使用。
  • 另外,很多語言的編譯器能夠共享VM後端程序,允許diamante共享和語言互用性。比如,某種語言善於科學計算,主要是因爲它的中間代碼被翻譯成的機器語言在底層上是很高效的,如果我們能夠把另一種語言編譯到同樣的VM層,那麼另一種語言就能夠獲得這種高效的科學計算。

實現介紹

在本章中實現的命令有算術邏輯命令和內存訪問命令。
算術邏輯運算主要利用堆棧來進行實現。內存訪問命令,通俗來講就是將數據從內存中拿到堆棧中和將數據從堆棧中拿到內存中。所以,這兩種命令綜合起來,主要實現的過程就是:將數據從內存中拿到堆棧中,然後再堆棧中進行運算,然後再將運算結果從堆棧中存到內存中。
數據結構的實現:堆棧和虛擬內存段
實際上再本章的project中,並不需要一個實際的數組或者列表來實現堆棧和內存段,但是要有邏輯上的概念。
在Hack計算機平臺中,內存爲32K。其中前16K作爲通用RAM使用,後16K用於I/O設備的內存映像。對於前16K的通用RAM,VM將其劃分爲8個獨立的虛擬內存段,下面是具有的劃分介紹:
在這裏插入圖片描述
argument,local,static,this,that,temp這些段在下面由具體的介紹。這裏要注意兩個段,constant和pointer。constant並不需要佔用RAM段,它是通過直接在高級語言中使用int變量來實現。pointer段實際上就是由RAM[3]和RAM[4]組成,下面具體介紹RAM[3],RAM[4]。
在這裏插入圖片描述
在這裏插入圖片描述
SP:初值爲256,此時表示棧空
LCL:local段的基址並不是固定的,這並不是重要的,重要的是,我們只要記住local段的基址就可以了,至於基址是什麼,等待程序進行分配
ARG:argument段的基址也不是固定的,我們只要記住argument段的基址就可以了
THIS:this段的基址也不是固定的,我們只要記住this段的基址就可以了
THAT:that段的基址也不是固定的,我們只要記住that段的基址就可以了
RAM[5-12]:這8個內存單元是直接保存的內容,而不是基址,它與之前幾個單元的差別在於,對temp進行操作的時候要比對this,that,local和argument段進行操作的時候少基址的獲取。對temp訪問的時候直接在R5上加上偏移量就是本次存取的內存單元
RAM[13-15]:這3個內存單元作爲通用寄存器,在本章中,主要的作用就是暫時存儲從棧中彈出的數據,或者暫時存儲通過基址計算出來的地址。
RAM[16-255]:這個段中的內存單元主要是分配爲VM中的靜態變量,即使用static標識的變量,在本章中使用順序分配的方式來進行的,而在本課程提供的VMEmulator中使用的是基址和偏移量的方式來進行分配的,但這對於程序測試並沒有影響,所以不必要擔心這個地方
RAM[256-2047]:這個段是棧區,當做棧來進行使用,注意對棧進行操作的時候,要進行棧頂地址的改變
在本章中就使用了這些內存段。
綜合內存映射分析堆棧運算
做好本章的項目,理解好內存映射是關鍵,只有理解了內存映射才能知道去哪裏取數據,將數據存儲到哪裏。綜合來看,本章的大致思路就是:從RAM[1-4]中找到基址,然後再根據偏移量計算出地址,然後去獲取數據,再將數據放入堆棧中,在堆棧中完成一定操作後,再將結果從堆棧中彈出,然後放到指定的內存單元(這裏實際上還需要計算基址和偏移量)。不同的是temp段,它可以直接在RAM[5]上加上偏移量得到存儲單元的地址。在整個操作過程中,如果需要使用除D寄存器和A寄存器之外的寄存器暫時存儲結果的時候,就會使用到RAM[13-15]的通用寄存器。

實現步驟

1、按照書中7.5所推薦的實現順序依次實現5個vm文件的轉化。
2、對於每一個文件,先在VMEmulator中運行.vm文件和xxxxVME.tst,通過觀察其每一步是如何實現的,深入理解VM語言中push,pop和各個參數的實際意義。
3、自己手寫相關的Hack彙編語言代碼,對每個內存段,都要至少寫上一個例子
4、將轉換過程用高級語言實現,測試並修改,抽象出方法,實現代碼複用


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章