Jump to content
43oh

Why is MSP430's Stack Poniter(SP) always alligned to even address?


Recommended Posts

While I was reading through the MSP430's User's guide, I came to know that its stack pointer is alligned to even address. (Read Pg.189 of http://www.ti.com/lit/ug/slau208m/slau208m.pdf)

 

Question 1: Why is it so ? Why is the stack pointer alligned to even address?

 

 

 

Using msp430-gcc, I wrote a C program which contained a global 'char'(8 bits) array and which will print on UART the address location of each array element. What I found was that each array element was at '+1' from the previous address i.e

Address of a[0] is 2400

Address of a[1] is 2401

Address of a[2] is 2402

Address of a[3] is 2403

 

Question 2: Here I can see that all array element's are not alligned to even address i.e a[1], a[3] are at odd address. Arrays are stored in RAM and are accessed via stack pointer. How did the stack pointer store an odd address ?

 

 

 

As per my understanding, each address location in RAM can store 16bits of data(since MSP430) irrespective of even or odd address location. If I write the same above program with 'int'(16 bits) instead of 'char'(8 bits), then I get the array address '+2' i.e

Address of a[0] is 3400

Address of a[1] is 3402

Address of a[2] is 3404

Address of a[3] is 3406

 

Question 3: But my above experimentes showed that each address can store only 8 bits instead of 16. Why ?

Link to post
Share on other sites

16 bit operations can only occur on even addresses, just FYI. When 16bit operations occur the least significant bit of the address is ignored and assumed to be 0. Just a stated quirk of the architecture. This has bit me in the ass before when casting an arbitrary pair of bytes inside a uint8_t array to type "int"... weird results occurred.

 

Sent from my Galaxy Note II with Tapatalk 4

 

 

Link to post
Share on other sites

Likewise though 8 bit instructions exist, i.e. the ASM instruction has a ".B" at the end to designate Byte. These can perform on arbitrary odd or even addresses, but any that copy byte data to a local register must acknowledge the fact that registers are 16-bit. For the most part this isn't an issue except with Signed data, where a signed 8-bit integer must have the SXT instruction applied to its data in register to make it work correctly as a signed 16-bit integer. This should be transparent to your C program though since the compiler takes care of it.

 

Sent from my Galaxy Note II with Tapatalk 4

 

 

Link to post
Share on other sites

To answer the last question, addresses only store 8 bits, it's just that the MSP430 only performs 16 bit operations on even addresses (assuming the stated address contains the least-significant byte, and the odd address 1 higher contains the most significant byte; i.e. Little-Endian). FYI if you want to see an architecture that has truly 16-bit "bytes", take a look at the TI C2000 series (there is a LaunchPad for the Piccolo F28027 series chip for $17). That's a TI proprietary DSP/MCU 32-bit arch with 16 bit "bytes" and 32-bit words.

 

Sent from my Galaxy Note II with Tapatalk 4

 

 

Link to post
Share on other sites

As @@spirilis said, a quirk of the architecture. It is actually a good feature, as it greatly simplifies the memory hardware. If it were not for this, then either two memory accesses would be needed to access a 16bit word (like in the8085, Z80, etc) with a bit more logic to handle it, or a LOT more real estate would be needed for memory access logic, taking away space for other options and reducing the manufacturing yield, raising cost for the device.

Link to post
Share on other sites

Just to add. Robomon, you sound like your mistaking the stack Pointer, SP, for indirect addressing. The SP is a special register. It is linked to special function when push/pop/call/ret/reti instructions are executed.

 

Your byte array would be compiled down to an indirect access, using a register like so:

 

mov.b @r10,r11 or equiv. mov.b 0(r10),r11

 

Where r10 specifies an address (doesn't have to be word aligned), and after executed r11 would be equal to the data contained at that address.

Link to post
Share on other sites

What @@spirilis said about 16-bit operations needing to be aligned is correct and applies to word operations regardless of addressing mode. The insight with the stack pointer specifically is that, at any moment when interrupts are enabled, the MCU must be able to push the program counter and status register onto the stack as words to execute an interrupt. Thus the stack pointer must at all times be 16-bit aligned.

 

Also as noted, word access to odd-byte-aligned data gets the wrong answer. Sometimes when working with mapped structures (e.g., network packet headers) you might find the structure declaration annotated with __attribute__((__packed__)) which indicates that the native alignment requirements might not be satisfied (e.g., if some idiot defines a structure that begins with three uint8_t followed by uint32_t). Use of a packed structure on the MSP430, even if it happens to be aligned for some particular instance, has a huge impact on code size as the compiler has to build the multi-byte values up by independent byte read and swap operations.

 

So only used the packed annotation on structure declarations when you absolutely have to; and, where possible, lay out your structures so they're naturally 16-bit (or, better, 32-bit) aligned.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...