如果我有一個具有以下特征的 CPU/系統...
- 16 位架構(16 位暫存器和總線)
- 共 8 個暫存器
- 一套64條匯編指令
并假設我的組裝說明遵循格式......
OPCode (6 bits) Register (3 bits) Register (3 bits) Unused (4 bits)
** Example Instructions (below) **
Assembly: LOAD R1, R7 (Loads value of address stored in R1 into destination register R7)
Machine: 110000 001 111 0000
Assembly: STORE R1, R7 (Stores value in R1 into destination address stored in register R7)
Machine: 110001 001 111 0000
這些型別的指令對我來說很有意義,因為所有必需的位都非常適合 16 位格式,因此可以放入指令暫存器(保存 16 位),但我對如何將所需地址放入暫存器開始感到困惑由于這個指令長度限制?
如果該系統上的地址是 16 位,在我看來,我需要超過 16 位來表示一條指令,該指令將在我什至可以使用諸如 LOAD 或 STORE 指令之類的東西之前將地址值分配給任何給定的暫存器。 .
OPCode (6bits) destinationRegister (3 bits) addressLiteral (16 bits) ???
然而,像這樣的東西不適合我的 16 位指令暫存器。我在這里不明白什么?非常感謝任何幫助,謝謝!
uj5u.com熱心網友回復:
定長指令集:
LC-3 是一種 8 暫存器機器,具有固定大小的 16 位指令:它允許在某些 16 位指令中存在 9 位偏移。9 位偏移量用作立即數以形成相對于 pc 的地址,從該地址加載完整的 16 位值作為資料。因此,訣竅是將完整的 16 位值作為資料定位在使用它的代碼附近的某個位置(例如,在 /-256 個字內)。
MIPS 是一個 32 位指令集,位于 32 位地址空間中。使用兩條指令,每條指令都有 16 位立即數,可以組成一個完整的 32 位地址。
Hack / nand2tetris 有 16 位指令,并且有一個特殊的形式用于加載常量/地址,指令形式有一個位表示它是否是 A 型別,然后允許 15 位的常量或地址。
MARIE 是一個累加器機器,有 16 位定長指令,但只有 4k 的記憶體,所以允許在 16 位指令中嵌入 12 位絕對地址。
PDP-8 是一種累加器機器,在 12 位地址空間中有 12 位指令。指令可以直接參考附近的記憶體(在與代碼相同的 128 字頁內),或零頁上的任何東西(lowmem,也是 128 字)。
可變長度指令集通常允許在指令之后立即出現全長,例如 x86、68000 等。處理器將自動將這種立即數的大小包含在指令的全長中。
為了獲得更多元資料,指令集具有格式,并且指令集中的格式會有所不同以適應不同型別的操作,例如 3 reg 與 2 reg 加上 large-ish 立即數。這一切都與指令編碼有關,這里的部分想法是為軟體提供所需的功能,同時保持硬體實作的可管理性。
在設計 ISA 時,需要考慮很多事情。一是位置無關代碼,它允許代碼在地址空間的任何地方加載,甚至在不同地址空間的不同位置共享;理想情況下,代碼將在沒有任何運行時重定位的情況下運行,因此代碼可以是完全不可變的。動態可加載共享庫 (DLL) 也有一些注意事項。
因此,pc-relative 尋址模式非常有用,并且絕對地址應該限制在資料中,并且不允許在代碼中使用,這與 LC-3、MARIE、PDP-8 不同。
uj5u.com熱心網友回復:
沒錯,在具有與地址和暫存器字長相同的固定寬度指令的類似 RISC 的機器中,需要多條指令才能在暫存器中生成任意常數。
你可以做
- 具有它的 ISA 上的 PC 相關負載(例如 ARM,當您撰寫類似的東西時,匯編器可以自動生成附近的“文字池”
ldr r0, =0x1234567) - 像 RISC-V 這樣的 PC 附加功能
auipc - PC 相對縮放偏移量,如 AArch64
adrp(逐頁)/add(用頁內的偏移量修復它,或使用低 12 位作為ldr指令內的偏移量) - 或經典的
lui/addi用于任意非地址常量,兩個立即數的寬度加起來等于字長(如 MIPS 16 16,或lui來自普通 I 型指令的 低 12 的 RISC-V 高 20)
您通常需要一個指令格式的操作碼,該指令格式需要 1 個暫存器,并將其余部分用作立即位,從而為您提供最大空間。
在您的情況下,6 個操作碼位 1 個暫存器將占用 9 個位,只剩下 7 個立即位。
所以這不是很多,甚至不足以在 2 條指令中生成一個 16 位常量,即使使用添加或 OR 到一個暫存器底部的第二個操作碼也是如此。除非您想犧牲多個操作碼(例如,使用操作碼的低位作為額外的立即位),否則這不是很好。
因此,您可能希望使用 PC 相對負載作為生成大常量的主要方式。(所以一個操作碼,1 個暫存器,留下 7 位偏移量,可能按 2 縮放,所以它是字對齊的)。
或者一條特殊指令,將整個下一個指令字作為立即數讀取。解碼可以將此指令視為跳過資料以及加載該資料。(在一個簡單的標量流水線設計中,可能將其從獲取階段拉出并在管道的其余部分發送一個 NOP。它需要一堆特殊情況,并且如果您的管道的危險檢測仍在查看它,可能會有性能坑洼在替換為 NOP 之前。并在路徑指令位中放置一個額外的多路復用器或 AND 門進入解碼階段。)我不知道是否有任何真正的 ISA 真的這樣做;一些具有 16 位壓縮指令的 32 位 ISA(如 ARM Thumb 模式或 RV32c)具有 2 或 4 位元組的可變寬度指令,由前 2 位元組塊中的一些易于解碼的位發出信號。
uj5u.com熱心網友回復:
我假設這是一個虛構的指令集架構,因為基于這個問題它似乎并不真實。
地址通常使用“立即”樣式指令從程式加載,因此需要“op reg1 reg2 padding”形式之外的指令
例如,在 MIPS 中,您可以使用 Load Upper Immediate 和 Load Immediate 將 32 位值加載到具有兩條 32 位指令的暫存器中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/481974.html
