z80:The Stack

From Learn @ Cemetech
Jump to navigationJump to search

Consider the following scenario. You want to write a loop that will continuously display the getkey code for the key you press, until you press enter. The program would look something like this:


   Loopz:
   bcall(_GetKey)
   bcall(_ClrLCDFull)
   
   cp 5	 				;If enter is pressed,
   ret z					;then return
   
   ld hl,YouPressed
   bcall(_PutS)
   ld h,0
   ld l,a					;load a into hl
   bcall(_DispHL)			;display the number
   jr Loopz
   
   YouPressed:
   .db "You pressed key #",0


If you compile and run this, it will always give out the number zero. Why? The answer is that _ClrLCDFull, among most other ROM calls, clears many of the registers. You could try loading a into another 8-bit register, but _ClrLCDFull clears ALL the registers, so that just won't work. Fortunately, there is an area of memory called the stack. The numbers stored in registers can easily be copied into this area, using a command called push. Push take a 16-bit register as an input. There is another command, called pop, which recalls the value at the top of the stack into the given register. See the edit below:


   Loopz:
   bcall(_GetKey)      ;returns value of pressed key into 'a'
   push  af               ;push requires a 16-bit register
   bcall(_ClrLCDFull)
   
   pop  af               ;pop requires a 16-bit register
   cp 5	 				;If enter is pressed,
   ret z					;then return
   
   ld hl,YouPressed
   bcall(_PutS)
   ld h,0
   ld l,a					;load a into hl
   bcall(_DispHL)			;display the number
   jr Loopz
   
   YouPressed:
   .db "You pressed key #",0


You are not required to pop into the same register you pushed. Also, while the stack can hold quite a few variables, it is not of infinite size. Please know that, while you will likely never achieve this, continuing to push values without popping them will overflow the stack and corrupt adjacent memory areas.