从MIPS中的内存加载字节/半字
我被要求使用.byte和.word指令创建一个数据段,以存储值0x01、0x02、0x03、0x04为字节和值0x12345678。我的代码是:
.data
b1: .byte 0x01
b2: .byte 0x02
b3: .byte 0x03
b4: .byte 0x04
w1: .word 0x12345678
然后,我想使用LBU,LHU和LW加载到$ T0,$ T1,$ T2的值:0x01、0x0201和0x12345678。
我正在为此做的是:
lbu $t0,b1 #this works
lhu $t1,0(b2) #this doesn't work, gets an error
lw $t2,w1 #also works
我的错误是例外和Inst/Data Fetch中的不重对地址:0x10010001 。 如何将超过1个字节作为半字节加载?我对数据段中变量的声明是否错误?我可能想要SMTH喜欢:
byte_array: .byte 0x01,0x02
谢谢大家的帮助。
I am being asked to create a data segment using the .byte and .word directives to store values the values 0x01, 0x02, 0x03, 0x04 as bytes and the value 0x12345678 as a word. My code would be:
.data
b1: .byte 0x01
b2: .byte 0x02
b3: .byte 0x03
b4: .byte 0x04
w1: .word 0x12345678
Then I want to use the lbu,lhu and lw to load into $t0,$t1,$t2 the values: 0x01, 0x0201 and 0x12345678 respectively.
What I am doing for that is:
lbu $t0,b1 #this works
lhu $t1,0(b2) #this doesn't work, gets an error
lw $t2,w1 #also works
My error is exception and unaligned address in inst/data fetch: 0x10010001.
How do I load more than 1 byte as a halfword? Is my declaration of variables in the data segment wrong? Do I maybe want smth like:
byte_array: .byte 0x01,0x02
Thank you all for the help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您正在尝试加载一个半单词(
lhu
),该单词被声明为.byte
。 这是一个尺寸不匹配,这是您要遇到的错误。但是处理器并不关心尺寸不匹配,而是对齐。 因此,如果您想加载半词(两个字节),它们必须以均匀的字节边界启动,而您的数据设置并非如此。
lhu $ t0,b1
将工作,lhu $ t0,b3
和lhu $ t0,w1
,因为这些数据在甚至地址。 但是,b2
和b4
在奇数地址。AC编译器首先不允许您执行尺寸不匹配的负载,而不会进行严重的铸造,这会让您回到MIPS上的这些不规则的错误。 此外,X86处理器将允许未对准的访问权限,尽管在某些情况下,这些处理器比对齐的等效物要慢。
由于未对准的访问需要更多的硬件,而且编译器通常可以使用其类型系统来防止它们避免这些问题,因此某些设计选择放弃额外的硬件和MIPS是其中之一。
您还可以通过插入填充来更改对齐方式 -
b1
&B2
将更改B2
的对齐方式允许加载B2
和B3
使用lhu
。 因为w1
被声明为.word
汇编程序知道它需要对单词进行排列,因此请插入b1
& amp;b3
将导致W1
需要3个字节附加的对齐填充(由于使用了.word
数据声明,汇编器将提供该字节)。当您使用这种尺寸不匹配时,也将出现Endianness的问题。  MIPS模拟器将使用与基础处理器相同的Endianness,因此加载2个字节时通常会看到几乎没有Endian行为。 如果您声明两个
.bytes
而不是使用一个.HALF
您必须选择一个字节订单。You're attempting to load a half word (
lhu
) that is declared as a.byte
. That is a size mismatch, which goes to the error you're getting.But the processor doesn't care about the size mismatch, but rather the alignment. So, if you want to load a half word (two bytes) they must start on an even byte boundary, which isn't the case for your data set up.
lhu $t0, b1
will work, as willlhu $t0,b3
, andlhu $t0,w1
as well because these data are at even addresses. However,b2
andb4
are at odd addresses.A C compiler would not let you perform the size mismatched loads in the first place, without some serious casting, which would get you back to these unaligned errors on MIPS. Further, an x86 processor would allow the misaligned access, though in some cases those would be slower than the aligned equivalents.
Because misaligned accesses require more hardware and also that compilers can generally avoid these problems using their type systems to prevent them, some designs choose to forgo the extra hardware and MIPS is one of them.
You can also alter the alignment by inserting padding — one extra byte inserted between
b1
&b2
would changeb2
's alignment allowing to loadb2
andb3
usinglhu
. Becausew1
is declare as a.word
the assembler knows it needs to be word aligned, so inserting that one byte betweenb1
&b3
will causew1
to require 3 bytes of additional alignment padding (which the assembler will provide due to the.word
data declaration being used).When you use this kind of size mismatch, there will also be the issue of endianness. The MIPS simulators will use the same endianness as the underlying processor so you'll generally see little endian behavior when loading 2 bytes. If you declare two
.bytes
instead of using one.half
you will have to pick a byte order.