Machine Code Programming — Understanding the Stack

Author(s): Ian Logan
Publication: Syntax
Pub Details: Syntax/Syntax ZX80 v3 n8 (Volume 3, Issue 8)
Date: August 1982
Pages: 19

Often when writing machine code (MC) programs, it’s useful to keep the MC above RAMTOP. But few people understand how to move RAMTOP and the Z80’s stack pointer from within MC. The following details let you protect your MC programs from being overwritten by using the stack.

In the ZX80/1 with 8K ROM, the system variable RAMTOP holds the address of the first location above usable memory, whether the top of available RAM or as specified by the programmer.

The next two bytes, going down from RAMTOP, are always 3Eh and 00h. This pair of bytes marks the top of the GOSUB stack and constitutes an invalid line number. Using a RETURN command that fetches line 3E00 (15872 in decimal) leads to a “7” error.

Below the top marker of the GOSUB stack are the return line numbers of any GOSUB loops that are active. However, most times a machine code programmer isn’t dealing with BASIC subroutines; hence the GOSUB stack will consist of the top marker alone.

Next comes the point which, in my manual (p.171) is explained wrongly–the system variable ERR-SP, the error stack pointer, points not to the GOSUB stack but to the two bytes below it. These two bytes always hold the BASIC LINE-RUN return address, 0676h. The interpreter always returns to this address after executing subroutines involved in the interpretation of a single line.

The normal machine code stack is below the LINE-RUN return address.

An important point to note is that if an error occurs during part of the interpretation of a BASIC line, all the MC stack’s details are discarded as a return is made to the address held in ERR-SP, ie., 0676h.

Creating a new stack under programmer’s control involves correctly placing four bytes–3Eh, 00h, 06h and 76h–and giving appropriate values to the stack pointer and ERR-SP. The following routine shows one way to do this:

Mnemonic         Comment
LD HL,+.... ;your choice for RAMTOP
LD (RAMTOP),HL ;enter it
DEC HL         ;point to 1st location
LD (HL),+3E ;the impossible line #
DEC HL         ;point to 2nd location
LD (HL),+00 ;the line #'s low byte
DEC HL         ;point to 3rd location
LD (HL),+06 ;return address-high
DEC HL         ;point to 4th location
LD (HL),+75 ;low byte of address
INC (HL)       ;so as to avoid "76"
LD (ERR-SP),HL;this is to be ERR-SP
LD SP,HL       ;and the machine code
                stack pointer
continue....

This routine lets you run a MC program above RAMTOP that will not be overwritten by use of the stack. You can make a perfectly valid RETurn to BASIC if needed.

Note: As I mentioned, whenever an error occurs during the interpretation of a BASIC line, the machine code stack is cleared. But the GOSUB stack is left untouched. Hence “active” GOSUB return addresses remain on the stack, using up RAM at 2 bytes for each address.

It remains to be seen if this “bug” occurs in the monitor program of the ZX Spectrum.


For further details, see Dr. Logan’s books, Understanding Your ZX81 ROM and Sinclair ZX81 ROM Disassembly, Part A and Part B (with Dr. Frank O’Hara). All three are available direct from Ian Logan, 24 Nurses Lane, Skellingthorpe, Lincoln LN6 5TT, UK, or from any North American distributor for Melbourne House Publishing.–AZ