Home > Software design >  Load bytes/halfwords from memory in MIPS
Load bytes/halfwords from memory in MIPS

Time:04-26

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.

CodePudding user response:

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.

  • Related