前言
在半年前,我萌生了創造一門獨特的編程語言的想法,大約三個月前,腦中的這個想法逐漸變得清晰,我想實作一種可以不用鍵盤就能撰寫代碼的語言,比較準確得說應該是一門圖形化編程語言,不完全是像藍圖腳本那樣,而是結合代碼和圖形的優點,
設想中它是一門高級解釋型語言,所以我先命名它為“H”語言,意為高級,但我能力和水平非常有效,在實作的準備程序中就被絆倒了,于是我開始考慮將它實作為靜態編譯語言,先編譯為中間代碼,再解釋執行,
這篇文章介紹的就是這當中的中間代碼,因為它層次比"H"低,所以我命名為“L”語言,
這段時間我暫時放下之前GBA上的光線追蹤,開始設計L語言的指令集和虛擬機,現在虛擬機可以高效的運行指令位元組碼,并呼叫系統函式,實作輸入輸出等功能,這篇文章記錄了目前的進度,
指令設計的基礎應該是虛擬機的架構,因此我先簡要說明虛擬機特點,然后是指令集特點,最后詳細介紹指令設計程序,
虛擬機
通過中間代碼在不同架構,不同平臺的系統上運行程式的方法大概叫虛擬機技術,例如JAVA和.NET都是運行各自指令集的虛擬機,
我的虛擬機設計的目標是為了方便運行我的H語言,我將他稱為LVM,意為低級虛擬機(和LLVM名字很像 : D 我也是事后發現的),

學過計算機架構的也許知道基于堆疊的虛擬機和基于暫存器的虛擬機,我的LVM是基于暫存器的,但有它自己的特點,
在現代計算機中,函式呼叫需要保存暫存器,移動暫存器和壓堆疊出堆疊,會占用很多時間,這是因為暫存器的數量有效,而在虛擬機的設計中,完全可以不考慮暫存器的限制,例如可以給每個函式呼叫分配一組記憶體模擬的虛擬暫存器,這樣就不必保存和恢復現場,
我則采用了一種暫存器指標的方法,暫存器指標指示暫存器視窗的位置,呼叫函式會移動視窗位置,且原視窗和新視窗位置存在重疊,用于傳遞引數,

結合此圖,函式呼叫的程序為
- 呼叫者把引數放到暫存器視窗的末尾,
- 呼叫者將視窗后移,使原來的末尾變成開頭.
- 呼叫者把PC保存到視窗前之前,
- 呼叫函式(PC跳轉),
- 被呼叫函式執行完后,從視窗前讀取PC,回到呼叫前位置,
- 最后將視窗移回原位,
通過這種方法既可以不用保存現場,也不用移動暫存器,在寫這篇文章時,我才查到這種方法在我之前就已提出,名稱是重疊暫存器視窗技術,用于精簡指令集處理器中,其中的范例是SPARC,因此我的虛擬機也可稱為基于重疊暫存器視窗技術的虛擬機,
截至目前為止,虛擬機的結構如下:

可以看到:
- 暫存器視窗有16個暫存器,而虛擬暫存器有一萬多個,這就是軟體虛擬的好處,是SPARC等硬體處理器不能做到的,
- 雖然現在留有SP暫存器,但實際上除了暫存器列,并沒有堆疊,因此也沒有堆疊指令,我想先探究依靠靈活的暫存器視窗和暫存器列能否替代堆疊,
- 指令譯碼后儲存為VL位元組碼,加載到記憶體后由vcode指標連接到虛擬機,
- 沒有使用標志位(或者叫程式狀態字)
附帶一提暫存器統一是32位或64位,目前按32位設計指令,
指令集
很隨意的命名為VL指令集,代表變長低級指令集,此外編譯器已經寫好,可以將其對應的LASM匯編語言編譯到VL位元組碼,
目前指令約80條,包含暫存器移動、記憶體讀取儲存、加減乘除、移位、位運算、跳轉、分支、暫存器視窗操作和系統指令,
個人感覺VL指令集功能應該在精簡和復雜指令集之間,
正如前面所說,指令是依附于機器的,所以指令的Call和Return的操作都比較特殊,還有特殊的暫存器視窗移動指令,但沒有堆疊操作指令,
因為面向的是軟體層面,且是實時解釋執行的,這些指令的位元組碼都盡量比較規整,例如操作碼是1位元組的,兩個暫存器各4bit拼一起也是1位元組,盡量避免讀取譯碼的額外操作,指令不是像大多精簡指令集一樣定長,而是以位元組為單位,長度在1-6位元組之間,這會導致指令執行增加一點變數,速度受到影響,但節約了大量的空間所以也不用心疼,
這是一些位元組碼的安排(靠右為低位元組):

設計指令集
指令集的組成和設計指令集的程序我放到下一篇文章中詳細說明,
而下下篇文章,我會繼續介紹LVM虛擬機的實作程序和優化心得,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/51151.html
標籤:C
下一篇:從零開始設計指令集的程序
