我正在做一个硬件,其中我必须为LDRH指令制作一个存储器指令格式和单个数据路径周期。计算完地址(rn +扩展imm12)后,我们得到一个32位值存储在Rd中,但是32位值(二进制)中的8位要存储在Rd中(我知道这8位将存储在低位路的尽头?
我也在Arm32中工作,并以LDRH Rd,[Rn,#imm12]为例。
这是问题
请考虑ARM ISA中的LDRH(加载半字)指令。该指令的格式如下:LDRH Rd,[Rn,#imm12]该指令从(Rn + 0扩展立即值)指定的地址中读取8位(1字节)数据,并将数据存储为将符号扩展的32位值扩展到目标寄存器Rd。
(a)给出LDRH指令的32位指令格式。根据您对ARM体系结构的了解来命名格式。清楚地标记所有指令字段,并以位为单位提及每个字段的大小。
(b)。在分配的下一页上修改单周期ARM处理器以实现LDRH。显示数据路径中的所有必要更改,并绘制实现指令可能需要的任何其他控制信号。请使用不同颜色的笔/突出显示(如果提供数字解决方案,则使用不同的字体和线条颜色),而不使用图表上的颜色,以使标记更容易理解您的解决方案。
答案 0 :(得分:0)
如何知道那半个字位(8位)...
...并将数据作为符号扩展的32位值存储到目标寄存器Rd中。
在ARM术语中,“ word ”表示32位,“ 半字”表示16位。
此外,LDRH
指令不会符号扩展,但会零扩展。
此处描述的指令是LDRSB
,而不是LDRH
。 LDRSB
符号扩展8位。
计算地址后……我们得到一个32位值存储在Rd中,但是32位……中要存储8位?
计算出的地址不存储到任何寄存器中。该地址用于寻址RAM(或任何类型的内存)中的一个字节。
换句话说:计算出的地址是内存中某处的地址。
将读取存储在该地址的字节。
该字节将被写入寄存器Rd
的低8位。由于指令对值进行符号扩展,因此读取值的值位7将被复制到Rd
的位31 ... 8。 (假设我们正在谈论LDRSB
。)
之所以这样做是因为(在十进制中)当在“零”数字前添加一个正数(在二进制系统中:位),而在二进制补码算术中,在“一”数字之前添加一个负数则保持相同:
decimal 12 = decimal 0000012
01100 = 000000001100 = decimal 12
10100 = 111111110100 = decimal -12
...如果使用二进制补码设置了最高位,则数字将被解释为“负”数字。
指令LDRB
将对值进行零扩展,这意味着二进制数不会解释为二进制补码,而会被解释为无符号的正数:
10100 = 000000010100 = decimal 20
因此,LDRB
只需将位31 ... 8设置为零。
对于16位指令(LDRH
和LDRSH
),将读取两个字节:
所计算地址的字节将被读入低8位,其后的字节将被读入15 ... 8位。在LDRSH
的情况下,第二个字节的最高位将被复制到位31 ... 16;在LDRH
的情况下,这些位将被简单地设置为零。
示例:
R0 = 1234000 (decimal)
Content of the memory:
Address 1234012: 9A (hexadecimal)
Address 1234013: 7A (hex.)
Address 1234014: BC (hex.)
Address 1234015: DE (hex.)
Address 1234016: 7E (hex.)
Program:
LDRSB R1, [R0, #12]
LDRSB R2, [R0, #13]
LDRB R3, [R0, #12]
LDRSH R4, [R0, #14]
LDRSH R5, [R0, #15]
LDRH R6, [R0, #14]
Results:
R1 = FFFFFF9A
R2 = 0000007A
R3 = 0000009A
R4 = FFFFDEBC
R5 = 00007EDE
R6 = 0000DEBC