This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CPU - Stack Pointer Question

I am reading about the Stack Pointer which I see is one to the special function register of the CPU.  I am trying to relate these register to my under standing of Port 1.  I understand Port 1 has multiple 8 bit registers.  Each register holds the place of one byte in memory.  For example P1IN may be 0x020.  Each one of the bits in each register relate to one of the pins and the value can be either a 1 or a 0.  That's clear to me.

As for the Stack Pointer I am getting lost with how it works.  Looking in the Family User's guide I see it is a 20 bit register which means that I have 20 places in Binary which can either be a 1 or a 0.  I see the function of this register is to hold the address of the instructions which are next in line.  I don't see how the the 20 bits of the stack pointer relate to these addresses.  I understand the Stack Pointer is hard wired to 0 so that is takes even words, but how is it taking multiple words if it is only 20 bits or 1.5 words.  I am attaching an image from the book I am reading which shows the addresses being added.  I do not understand how the register has so many bytes 0x0280, 0x027e etc.?

Any clarification would be greatly appreciated.

Take care,

Jon

  • I think I figured it out.  I apparently missed the fact that the addresses are stored in 128 Bytes of RAM.  The Stack Pointer simply holds the address of the top of the stack.

    Take care,

    Jon

  • Jon Thornham said:
    I am reading about the Stack Pointer which I see is one to the special function register of the CPU

    Not exactly. The 'special function registers (SFRs)' are located in the memory area, beginning at 0x0000.
    The SP is a processor register adn equal to R1, while th eprogram counter (PC) euqals R0 and the status register (SR) equals R2. R3 is for constant generator and R4 to R15 are fo general purpose.

    However, R0 to R3 can be used in any assembly instruction that can also use the other ones. In fact, many 'special' instructions have no physical representation. So a 'BR x' instruction is really a 'MOV x, R0' instruction (and not different from moving a value into a different register for calculations).
    And a "POP x" is rather a "MOV @R1+, x" (push, however, is a separate command, as there is no @-Rx pre-decrement addressing mode)

    About the workings of the SP/R1, you already got it. Indeed, R1 is a pointer to the top of stack. (hence its name) It is decremented before something is pushed to stack and incremented after something ahs been popped from the stack. The stack itself is plain ram. And there i snothing that prevents the stack from overflowign to variabel area or even into ram-less area. Same for an 'underflow' - you can pop form stack etewrnally and the hardware won't complain. WHen SR has reached 0xFFFE, you'll pop the reset vector next, adn then it will roll over to 0x00.

    I'm not sure whether the stack pointer is 20 bit, however. If so, then only on MSP430X devices. But even on those, a 20 bit SP doesn't make sense as the stack can only work on RAM and above 16 bit address range, there's only flash or vacant memory.

    BTW: on Microchips smaller PIC processors, the stack is done in hardware. There is no stack pointer and the size of stack spaces is limited and not usable for anything else than the stack. Here a push indeed stores the pushed value into a LIFO buffer.

  • Jens-Michael,

    That is excellent information.  I thank you for writing it.  Two follow up questions if you don't mind.  First, I am a C Programmer and it seems this stuff only really matters if you are dealing with assembly language.  If I understand correctly using C eliminates the need to program this yourself.  Is that all true?

    The second question has to do with what you said

    "WHen SR has reached 0xFFFE, you'll pop the reset vector next, adn then it will roll over to 0x00."

    Does this cause a problem?  If I am programming in C is this all looked after for me?

    Again thanks for the response.

    Take care,

    Jon

  • Jon Thornham said:
    If I understand correctly using C eliminates the need to program this yourself.  Is that all true?

    Mostly. The MSP has some functionality inside the status register, includign the interrupt enable bit and the controls for the low-power modes. So the compiler has some so-called 'intrinsics' which look like macros and add some specific assembly code to handle these things.

    Examples being the EINT() or __enable_interrupt() intrinsics. Or the __bis_SR_register(x) intrinsic that sets bits in the status register.

    There are other tweaks to the C language to deal with things like hardware interrupts (C itself doesn't know about interrupt service functions or interrupt vector tables) and a few more architecture-specific tweaks.

    Jon Thornham said:
    "WHen SR has reached 0xFFFE, you'll pop the reset vector next, adn then it will roll over to 0x00."
    Does this cause a problem?  If I am programming in C is this all looked after for me?


    Well, it will surely cause a problem, but if this happens, you'll had a problem long ago already.

    What I meant was: normally, the stack pointer is initialized to the upper end of ram. Say 0x8000. If you push something to the stack, the stack pointer is decremented to 0x7FFE and the pushed value is written at @R1 (to 0x7FFE/0x7FFF).

    However, nothing prevents your code from popping a vaoue from teh stack that was never written there. So the stack pointer reads from 0x8000/0x8001 (which in our example qould be the strt of flash) and return the value there, then incrementing to 0x8002. YOu can continue to pop values indefinitely. However, if you ever try to write something, it will be written to read-only flash (= discarded). Which will of course cause probelms. But the source of the problem happened when something was poppe dform stack that was never pushed there, and is a serious bug. However, normal compiled C code will never do this, except if you're using e.g. GOTO to jump into an ISR (which then wants to pop a status register content from stack at exit, which was never pushed on it) or similar constructs.

    For normal C programming, the linker will add soem standard code that copyies the init values for your variabels from flash to ram and initializes the stack pointer properly, based on teh configured target processor.

    However, there is nothing that prevents you from pushing data to stack until it grows so large that it floods into the data area with your variables, destroying the saved values, while any write to a varibale that hasb alread been washed away will alter the stack content.
    Yu can define a stack size in the project settings. This is, however, a minimum stack size settign and ensures that at linking stage there weill be at least that much ram unused (free for stack usage) after all variables have been placed in ram. And the debugger will tell you if the stack has exceeded this value. However, nothing will prevent the stack from growing, if you, e.g. go into an eternal recursion with your code. the stack will grow (and the stack pointer decrement) until it points below the ram area and the system will eventually crash (if this didn't happen before already).

     

  • Awesome info. Thanks for the time. 

    Take care,

    Jon

  • One thing I did (with Code Composer) to learn how the stack works was to step through various code while watching the registers and setting the memory view to the location of the stack.  It's pretty cool to see how a statement like "int x = 1" decrements the stack pointer when the function is called to make room for x, and later moves the value 1 onto the stack.  If you want to see it happen in more detail, step through the disassembly view.

  • Alex,

    I have been running through the register window when stepping through programs.  I dod not think to look at the stack though.  Awesome advice.  Thanks for suggesting it.  

    Take care,

    Jon

**Attention** This is a public forum