簡體   English   中英

通過匯編指令了解寄存器的地址分配

[英]Understanding address assignment to registers via assembly instructions

如果我有一個具有以下特征的 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 位指令寄存器。 我在這里不明白什么? 非常感謝任何幫助,謝謝!

  • 定長指令集:

    • 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 不同。

沒錯,在具有與地址和寄存器字長相同的固定寬度指令的類似 RISC 的機器中,需要多條指令才能在寄存器中生成任意常數。

你可以做

  • 具有它的 ISA 上的 PC 相關負載(例如 ARM,當您編寫諸如ldr r0, =0x1234567之類的東西時,匯編程序可以自動生成附近的“文字池”)
  • 像 RISC-V auipc這樣的 PC 插件
  • 與 PC 相關的縮放偏移量,如 AArch64 adrp (逐頁)/ add (使用頁內的偏移量修復它,或使用低 12 位作為ldr指令中的偏移量)
  • 或用於任意非地址常量的經典lui / addi ,兩個立即數的寬度加起來等於字長(如 MIPS 16+16,或來自lui的 RISC-V 高 20 + 來自普通 I 型指令的低 12 )

您通常需要一個指令格式的操作碼,該指令格式需要 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 字節塊中的一些易於解碼的位發出信號。

我假設這是一個虛構的指令集架構,因為基於這個問題它似乎並不真實。

地址通常使用“立即”樣式指令從程序加載,因此需要“op + reg1 + reg2 + padding”形式之外的指令

例如,在 MIPS 中,您可以使用 Load Upper Immediate 和 Load Immediate 將 32 位值加載到具有兩條 32 位指令的寄存器中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM