处理器指令编码可重定义的方法_从零开始设计四位栈处理器(2)——结构与指令集...
從零設計四位棧處理器(2)——結構與指令集
一句話概括: 在Toxic處理器中,萬物皆棧。
熟悉匯編語言的同學會了解,一般的匯編語言,會包含以下幾個部分:
在這期文章中,我們將通過類比的方法來解釋Toxic處理器的運行方法以及設計上作出的妥協。
上圖顯示的是RISC-V的最基礎的四類指令,其中R類負責寄存器與寄存器之間的運算操作,I類負責寄存器和小立即數之間的操作,S類負責寫入內存(讀取指令被歸結為I類內),U類負責處理大立即數以及PC相關的尋址。
一、寄存器
寄存器的本質是用來暫存數據,避免讀寫內存帶來的巨大性能開銷。
我們先舉一個R類RISC-V匯編的例子:
add x1, x1, x1
這條命令的意思是:將x1寄存器的值與x1寄存器相加,并且將結果寫入x1寄存器。
事實上這是一個非常典型的寄存器尋址的匯編指令,在X86構架、ARM構架和MIPS構架中幾乎都能找到相似的指令。
但是我們在Toxic處理器中并沒有這樣的指令出現。那么我們為什么不用這種類型的指令呢?
我們上面展現的匯編代碼來自RV32I指令集,本質上是一個32位整數指令集,在該指令集中總共定義了32個通用寄存器。我們為了尋址32個寄存器,在指令中每包含一個寄存器,需要花費log_2(32)=5比特的寬度。
而Toxic處理器是一個4位等長指令處理器,而4位二進制碼只有16種不同的組合,這也就導致了在Toxic處理器中應用這種“寄存器尋址”的體系是非常不現實的:一條指令總共只有4比特,算上操作碼占的空間,我們恐怕最多只能留2位給寄存器尋址,但這顯然是不夠的。所以既想維持4位的簡潔又想擁有更多的”暫存空間“要怎么辦呢?
于是我們引出了:Stack Machine(棧處理器)這個概念。
所謂棧處理器是相對于寄存器處理器而言的,一個棧處理器是不存在通用寄存器的,取而代之的是一個“棧”。棧這個概念相信各位已經非常清楚了,Toxic處理器里面的棧和我們通常說的棧道理上是完全相同的。不同之處在于:1. Toxic處理器的棧是由硬件邏輯門實現。2. Toxic處理器的棧,除了實現了push,pop之外,還實現了tos和ntos兩個功能。tos就是所謂的棧頂,ntos就是次棧頂,在訪問tos和ntos的時候不會改變棧內部的內容。
在這里,我們將這個作用是“替代通用寄存器”的棧命名為:數據棧。
二、地址
以RV32I為例,如果我們有一個32位寬度的總線,那么我們總共可以尋址的空間是2^32 Byte(假設每個地址尋1 Byte)。這個尋址空間說大不大,但是對于普通應用來說已經足夠了。
但是Toxic處理器是一個四位處理器,2^4=16 Byte的尋址空間對于幾乎任何程序來說都是不夠的。很自然的我們就可以想到去運用多個4位總線連接起來一同來尋址,這樣的話可以擴大我們的尋址空間。于是乎就出現了一個問題:到底要多大的尋址空間才好呢?在這里,Toxic處理器的設計給每個去嘗試實現它的人都留下了空間,我們規定:總線寬度只要為4位的倍數,都可以讓Toxic指令集良好的工作。
在開頭我們就說過:Toxic處理器中,萬物皆棧。與數據棧的思路相同,我們同樣用棧來表示一個總線地址,在此我們稱之為:地址棧。
8位的地址棧的實現與數據棧基本相同,為了避免混淆,我們暫時不引入更高位的地址棧的設計。
到此為止,我們已經講述了Toxic處理器中最重要的兩個部件。如果你感覺有似懂非懂的地方,沒有關系,在我們一步步解釋整個Toxic指令集之后你會有更清晰的認識。
三、立即數
立即數在處理器中的作用是將指令中的數直接作為處理器內的數據進行計算。
用RV32I指令集舉個例子:
addi x1, x1, 1
該指令的意思是:將x1寄存器+1的結果存進x1寄存器。在該指令中,數字1就是一個立即數。
對于我們的Toxic處理器來說,處理立即數的本質就是將我們指定的任何一個數字,push進數據棧內。
下圖是Toxic指令集的所有指令以及編碼:
在了解生成立即數的具體操作之前我們先看3個指令:P1, ADD, LS。
- P1: 將數據“1”push進數據棧。
- ADD:將數據棧tos和ntos的加和push進數據棧。
- LS:將數據棧中的tos左移一位。
明白了這三個指令的操作,我們來思考一下:如何把“5”這個數字push到數據棧內呢?
首先,5的二進制是:0101。我們有以下代碼:
P1 // tos為0001 LS // tos為0010 LS // tos為0100 P1 // tos為0001, 這時候之前的tos已經成為了ntos,為0100 ADD // 0001 + 0100 = 0101;這時候tos為0101,我們完成了將“5”push到棧頂為了更高效的生成立即數比如說:15(也就是二進制中的1111),我們引入了P11這個指令,P11所做的事情與P1類似,就是將0011給push到棧頂。
四、操作碼
操作碼是指在機械碼中存在的用來指定處理器指令的幾位。
在RV32I指令集中,我們可以看到0-6位都是“opcode”,也就是我們說的操作碼。
再次地,Toxic指令集是一個4位等長指令指令集。
然而不難發現,在Toxic指令集中,我們雖然只有4位的空間來描述一個指令,但是我們對于寄存器的尋址并不占用指令空間,對總線地址的訪問也不占用指令空間,甚至連對寄存器的操作都不占用指令空間。所以,到最后,所有4位空間,我們都將分配給操作碼。換句話說,在Toxic指令集中,所有機器碼都是操作碼。
(其實關于操作碼的界定問題,學術界也沒有一個非常準確的標準,比如說很多時候,RV32I的funct3都會被說成操作碼的一部分。但是這都不重要,只是個人的區分和習慣問題)
我們這期文章就暫時先講這么多,下期文章我們會更加仔細、更加完整的解讀這16條指令,并且聊一聊如何用Toxic指令集編寫一個真實有意義的程序。在講完指令集后會講一下整個Toxic處理器電路層面的實現。
當然,在那之前還有很多工作需要完善,大家可以先看看我的GitHub上Toxic_v2的英文文檔還有最近很快就要完成了的Toxic_v2模擬器,如果大家能給我點個星星,我會非常感謝:
文檔:https://github.com/Entropy-xcy/Toxic_v2
模擬器:https://github.com/Entropy-xcy/Toxic_v2_simulator
引用:
【1】 RISC-V ISA Specifications: https://riscv.org/specifications/
總結
以上是生活随笔為你收集整理的处理器指令编码可重定义的方法_从零开始设计四位栈处理器(2)——结构与指令集...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python冒泡算法_python_冒泡
- 下一篇: mac python安装太慢_【已解决】