gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Odd problem when reading from an address

#132815 - DiscoStew - Fri Jun 29, 2007 8:45 pm

I've read through a few posts concerning this type of problem, and what is known is that reading from a non-halfword aligned address would result in unpredictable values. However, what I am trying to do here is read a 4-byte value from an address which would be on a 2-byte aligned address, but not a 4-byte aligned address.

For some reason, in one part of a binary file I am reading from, I'm reading a 4-byte value from a 2-byte aligned address with no problems, but at another point in the binary file, the same kind of read is being done, but I'm getting an odd result. Let me give a more descriptive explanation...

Say I have data in my binary file as such (starting at 0x02000000) in little endian...

00 00 01 00 02 00 08 00 00 00 01 00 01......

So, I'm reading a 2-byte value at 0x02000002, which would net me 0x0001, correct? A 4-byte value at that same address, however, give me 0x00000001, and not 0x00020001. along with that, if I read 4-bytes from 0x02000006, I'm getting 0x00020008 instead of just 0x00000008. It's almost like when reading 4 bytes from a 2-byte aligned address, it reads 2 bytes from the address given, then reads the previous 2 bytes.

Is this correct, and is this how it is supposed to work? It's kind of odd that I get a problem in one part of the binary, but not in the other. But, if it is supposed to read this way, should I just read 2 bytes at a time manually, and put them together if I need a 4-byte value?
_________________
DS - It's all about DiscoStew

#132822 - Dwedit - Fri Jun 29, 2007 9:15 pm

Read this: http://nocash.emubase.de/gbatek.htm#cpumemoryalignments
Non-aligned reads rotate the memory around, Non-aligned writes ignore the lower bits of the address.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#132825 - DekuTree64 - Fri Jun 29, 2007 9:22 pm

I think reading from unaligned addresses is "undefined". But on ARM7 and ARM9, I'm pretty sure the exact behavior is that it loads the 4 byte unit (ignoring the lower bits of the address) and rotates it so the byte you requested is at the bottom of the register. So if you have

00 01 02 03

and load from address 3, you get

02010003

or if you load from address 2, you get

10003020

i.e. upper and lower halfwords are swapped (which is what's happening in your examples). You could probably use that effect for some fancy tricks, but I don't think it's guaranteed not to change on future ARM processors.

I think you'll just have to load the data in aligned units and OR them together.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#132833 - DiscoStew - Fri Jun 29, 2007 11:12 pm

Ok, so I guess I have 2 options.

1) ORing 2 halfwords together into a word

2) Adjusting the binary's format so that there won't be a way for accessing misaligned addresses, or in other words, "padding" between data types.

Considering my binaries I am creating are mostly made up of halfwords and only a few words, Option 1 would be the way to go. Going with option 2, in my case, would require more processing time on the DS, because I'd have to check if there is a padded space for every part that could potentially be off alignment.

Thx for the help everyone. Much appreciated.
_________________
DS - It's all about DiscoStew