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