从MIPS中的内存加载字节/半字

发布于 2025-01-23 13:45:35 字数 614 浏览 2 评论 0原文

我被要求使用.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

诗酒趁年少 2025-01-30 13:45:35

您正在尝试加载一个半单词(lhu),该单词被声明为.byte。 这是一个尺寸不匹配,这是您要遇到的错误。

但是处理器并不关心尺寸不匹配,而是对齐。 因此,如果您想加载半词(两个字节),它们必须以均匀的字节边界启动,而您的数据设置并非如此。

lhu $ t0,b1将工作,lhu $ t0,b3lhu $ t0,w1,因为这些数据在甚至地址。 但是,b2b4在奇数地址。

AC编译器首先不允许您执行尺寸不匹配的负载,而不会进行严重的铸造,这会让您回到MIPS上的这些不规则的错误。 此外,X86处理器将允许未对准的访问权限,尽管在某些情况下,这些处理器比对齐的等效物要慢。

由于未对准的访问需要更多的硬件,而且编译器通常可以使用其类型系统来防止它们避免这些问题,因此某些设计选择放弃额外的硬件和MIPS是其中之一。

您还可以通过插入填充来更改对齐方式 - b1& B2将更改B2的对齐方式允许加载B2B3使用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 will lhu $t0,b3, and lhu $t0,w1 as well because these data are at even addresses.  However, b2 and b4 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 change b2's alignment allowing to load b2 and b3 using lhu.  Because w1 is declare as a .word the assembler knows it needs to be word aligned, so inserting that one byte between b1 & b3 will cause w1 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文