Understanding Assembly MIPS .ALIGN and Memory Addressing

Sobiaholic picture Sobiaholic · Oct 26, 2013 · Viewed 27.6k times · Source

I'm taking this course, and I'm really struggling understanding the directive .align concept.

Here's an example, which I couldn't understand:

enter image description here

I know that inside the data segment, there are addresses, starting with 0x10010000,0x10010020,etc.

And I know, that inside each address, there are 8 memory fields, each has 32bit.

Now, what I don't understand is, how and why var2 inside the address 0x10010010? str1 is inside the address 0x10010003 because we reserved 3 bits for the var1.

The last thing is, what exactly the directive .align' doing? when I tested it in Mars4, it only shifted the data into the next memory field when I usedalign 3` and up, but I don't really get it.

I'm sorry if this is very confusing guys, I'm kind of desperate here.

Answer

Hans Passant picture Hans Passant · Oct 26, 2013

Alignment is important for a MIPS processor, it only likes to read multi-byte values from memory at an address that's a multiple of the data size.

The .ASCIIZ field can be placed anywhere since a string is read one byte at a time. So putting it at 0x10010003 is fine.

The .WORD field must be aligned to a multiple of 4. So it can't be put at 0x1001000E, the next available location after the string. The assembler intentionally shifts the value and leaves two bytes unused. To the next address that's a multiple of 4, 0x10010010.

The .ALIGN directive is a way to override the default alignment rules. The next field after the directive will be aligned to a multiple of 2 to the power of n where n is the .ALIGN value. In your case that's pow(2, 3) = 8 bytes.

Which is what you see happening, without the .ALIGN directive the .HALF field would be stored at 0x10010014. Not a multiple of 8 so it is moved to 0x10010018.

The example is otherwise artificial, no obvious reason to use the .ALIGN directive here since .HALF only requires an aligment to a multiple of 2 so storing it at 0x10010014 would have been fine.