Hello, The stack pointer for the chip I'm using is 8bits (address 256 bytes max). Is there any way to get around this limitation so I can have larger stack space? (without changing chips) Regards, KC
$
Dear Andrew Neil, When you use LCALL or ACALL to direct program to a function. May I know where the PC value is saved? and how does RET return restore the PC value when function ends? (if this value is saved to the stack, does it save the high order byte first or the low order byte?) I've also notice no difference in RET and RETI. Regards, KC
The LCALL and ACALL instructions store the program counter on the (hardware) stack, via the SP register. From the Intel MCS-51 instruction set manual: Operation: ACALL (PC)<- (PC)+ 2 (SP)<- (SP) + 1 ((SP)) <- (PC7.0) (SP)<- (SP) + 1 ((SP))<- (PC15.8) (PC10.0)<- page address Operation: LCALL (PC) <-(PC) + 3 (SP) <- (SP) + 1 ((SP)) <- (PC7.0) (SP) <- (SP) + 1 ((SP)) <- (PC15.8) (PC) <- addr15.0 So, for what it's worth, the return addresses get pushed low byte first ("little endian"), but the address field of the instruction themselves are actually stored high byte first ("big endian"). The hardware stack in the 8051 (SP pointing into internal RAM, usually "idata") is used pretty much only for return addresses, and occasionally for temporary storage. Parameters and local variables are not stored on the hardware stack, but instead assigned to fixed memory locations, which can be reused from function to function depending on the compiler/linker call tree overlay analysis. The "reentrant" keyword is used for functions that are recursive or that get called from multiple contexts where you really do need the usual C behavior of pushing parameters and auto variables onto a stack. This "simulated" stack does not use the SP register, but rather is built somewhere else in memory (depending on your memory model), possibly using the DPTR and xdata. The C51 manual discusses this briefly in "Function Parameters and the Stack" on page 119, "Reentrant Functions" on page 129, and the linker (Assembler/Utilities) manual "Overlaying Data Memory", page 261, and "Data Overlaying", page 280. The difference between RET and RETI is that RETI is "return from interrupt". The effect on the stack is the same; however, RETI also clears the interrupt logic in the 8051 and allows another interrupt of the current priority to execute. If a routine is an interrupt handler, it has to exit with RETI instead of RET. If a routine is not an interrupt handler, it should use RET. The C51 compiler knows which instruction to generate based on whether you declare the function as "interrupt" or not.
To program in assembler, you need to know & understand the processor's instruction set and artchitecture. You need to visit the following page & thoroughly read the 8051 "bible" documents before you do anything much else! http://www.8052.com/links.phtml (Look under the INTERESTING SITES heading)
TYVM!!!