Search code examples
assemblyavratmel

How to know if the stack pointer has reached the last location in SRAM?


Let's say that I have pushed a number of values into the stack of the SRAM of an ATmega324PB. The stack will begin from the end of the SRAM. Now, I want to pop these values one by one to a register. Basically I want to create a loop that pops one value to the register and then goes to pop the next value in the stack to the same register. The loop will continue until the stack pointer reaches the last SRAM location (which in ATmega324PB's case would be $8FF).

How can I make the loop stop when it reaches the last location of the stack (SRAM)?


Solution

  • You have to check values of SPH,SPL i/o registers, which store current stack pointer. It may be something like this:

    ldi r18, hi(RAMEND)
    rjmp enterloop // first jump to check
    loop:
    pop r20 // pop from the stack
    enterloop:
    in r16, SPL
    in r17, SPH
    cpi r16, lo(RAMEND)
    cpc r17, r18 // we have no comparison to immediate with carry
    brlo loop
    

    But I cannot imagine why you need such a weird way of the stack accessing. You can just simple set stack pointer to it's end

    ldi r16, lo(RAMEND)
    ldi r17, hi(RAMEND)
    in r18, SREG // save flags, including interrupt flag
    cli // lock interrupts until both registers are updated
    out SPL, r16
    out SPH, r17
    out SREG, r18 // restore interrupts
    

    you can also read a topmost address of RAM into r20 to achieve the same result.