# STM32 Memory Alignment unclear

As I'm reading the Mastering STM32 Book, I came across this graphic describing the memory map

So what I'm trying to figure out is whether my understanding of memory is wrong, or if the graphic is. It is my understanding that in the figure on the right, the 5th variable (a byte) should be at address 0x20000008. The memory addresses increase from right to left, and top to bottom. So the 1st variable would have bits 7 to 0 at 0x20000000, bits 15 to 8 at 0x20000001, so on so forth. Could someone point me in the right direction if I'm incorrect?

• Is this big-endian or little-endian? – Elliot Alderson Jun 12 at 20:02
• @Elliot-Alderson Little-Endian – ccolton Jun 12 at 20:15
• it is a pretty bad way to show it unless there is text you didnt provide that indicates that only one of the items on the right is unaligned and the rest are aligned. – old_timer Jun 13 at 15:06
• everything else on both sides is aligned. – old_timer Jun 13 at 15:06
• you are correct bits 7..0 are at address 0x20000000 and 15..8 at 0x20000001. and the 5th item is at address 0x20000008 – old_timer Jun 13 at 15:08

The only thing that is not aligned is the #4 word in the right-hand diagram.

Everything else in both diagrams is aligned on natural boundaries — bytes on byte boundaries (by definition, since it's byte-addressable memory), halfwords on halfword boundaries, and words on word boundaries.

The thing that is really weird about the right-hand diagram is that #4 word does not occupy a contiguous set of bytes, and this may well be a drawing error. For some reason, bytes are numbered right-to-left, but the objects are packed left-to-right. I would have expected those diagrams to look more like this, in which the packing is in the same order as the byte addresses:

Aligned

     3        2        1        0
+--------+--------+--------+--------+
|              word 1               | 0x20000000
+--------+--------+--------+--------+
|////////| byte 3 |   halfword 2    | 0x20000004
+--------+--------+--------+--------+
|              word 4               | 0x20000008
+--------+--------+--------+--------+
|////////| byte 7 | byte 6 | byte 5 | 0x2000000C
+--------+--------+--------+--------+
|/////////////////|   halfword 8    | 0x20000010
+--------+--------+--------+--------+


Unaligned

     3        2        1        0
+--------+--------+--------+--------+
|              word 1               | 0x20000000
+--------+--------+--------+--------+
| word 4 | byte 3 |   halfword 2    | 0x20000004
+--------+--------+--------+--------+
| byte 5 |          word 4          | 0x20000008
+--------+--------+--------+--------+
|   halfword 8    | byte 7 | byte 6 | 0x2000000C
+--------+--------+--------+--------+
|///////////////////////////////////| 0x20000010
+--------+--------+--------+--------+

• Thank you, your diagrams are what I would've expected. All things considered this just seems like a poor example considering even the unaligned data is mostly aligned. – ccolton Jun 13 at 15:52

That diagrams are wrong, it looks like the author could not decide whether the addresses increase from left to right or right to left, and changed his mind halfway through.

Here is my attempt, with addresses increasing left-to-right.

Aligned structure:  +------------+------------+------------+------------+ | 1 | | LSB word(32) MSB | | 0x20000000 0x20000001 0x20000002 0x20000003 | +------------+------------+------------+------------+ | 2 | 3 | ////////// | | LSB halfword(16) MSB | byte(8) | / unused / | | 0x20000004 0x20000005 | 0x20000006 | ////////// | +------------+------------+------------+------------+ | 4 | | LSB word(32) MSB | | 0x20000008 0x20000009 0x2000000A 0x2000000B | +------------+------------+------------+------------+ | 5 | 6 | 7 | ////////// | | byte(8) | byte(8) | byte(8) | / unused / | | 0x2000000C | 0x2000000D | 0x2000000E | ////////// | +------------+------------+------------+------------+ | 8 | /////////////////////// | | LSB halfword(16) MSB | /////// unused //////// | | 0x20000010 0x20000011 | /////////////////////// | +------------+------------+------------+------------+ 

Unaligned, a.k.a. packed structure:  +------------+------------+------------+------------+ | 1 | | LSB word(32) MSB | | 0x20000000 0x20000001 0x20000002 0x20000003 | +------------+------------+------------+------------+ | 2 | 3 | 4 > | LSB halfword(16) MSB | byte(8) | LSB ... > | 0x20000004 0x20000005 | 0x20000006 | 0x20000007 > +------------+------------+------------+------------+  > 4 (cont) | 5 |  > word(32) MSB | byte(8) |  > 0x20000008 0x20000009 0x2000000A | 0x2000000B | +------------+------------+------------+------------+ | 6 | 7 | 8 | | byte(8) | byte(8) | LSB halfword(16) MSB | | 0x2000000C | 0x2000000D | 0x2000000E 0x2000000F | +------------+------------+------------+------------+ 

• That would be the big-endian interpretation, but the OP said (in a comment) that it's little-endian. – Dave Tweed Jun 13 at 16:02
• @DaveTweed Big-endian means that the MSB would be stored at the lowest address (e.g. 0x20000000), and the LSB at the highest address (e.g. 0x20000003). My drawing is the exact opposite, it depicts the Little-Endian arrangement (STM32 is always little-endian), so as you can observe, LSB is at the lowest address (0x20000000) and MSB is at the highest address (0x20000003) – berendi Jun 13 at 16:36
• In that case, your drawing is simply a mirror image of mine. – Dave Tweed Jun 13 at 16:45
• @DaveTweed I chose left-to-right increasing addresses, as memory dumps are usually displayed that way. (Have you ever looked at a hexdump?) Well, perhaps it's the other way round in a right-to-left writing locale, but we are on an English language forum, discussing a textbook written in English. – berendi Jun 13 at 16:45