stacks treatise index |
1. Intro: stack basics |
2. subroutine return addresses & nesting |
3. interrupts |
4. virtual stacks |
5. stack addressing |
6. passing parameters |
7. inlined data |
8. RPN operations |
9. RPN efficiency |
10. 65c02 added instructions |
11. synth instructions w/ RTS/RTI/JSR |
12. where-am-I routines |
13. synthesizing 65816 stack instructions |
14. local variables, environments |
15. recursion |
16. enough stack space? |
17. forming program structures |
18. stack potpourri |
19. further reading |
A: StackOps.ASM |
B: 816StackOps.ASM |
6502 STACKS TREATISE
65c02's (and 65816's) added instructions, relevant to stacks
The 65c02 (ie, CMOS 6502) has many advantages over the original NMOS
6502, including additional instructions and addressing modes. Ones that are relevant to stacks, more or less in order of
importance to stacks, are:
mnemonic code description
PHX $DA push X onto the hardware stack, without disturbing A
PLX $FA pull X off the hardware stack, without disturbing A
PHY $5A push Y onto the hardware stack, without disturbing A
PLY $7A pull Y off the hardware stack, without disturbing A
STZ ZP,X $74 At the ZP addr indicated by the operand plus X, store 00.
STZ abs,X $9E At the 16-bit addr indicated by the operand plus X, store 00.
BIT ZP,X $34 (new addressing mode for the BIT instruction)
BIT abs,X $3C (new addressing mode for the BIT instruction)
JMP (abs,X) $7C (new addressing mode for the JMP instruction)
- "abs" means a 16-bit base address referred to in the two-byte operand, and
"ZP" means an 8-bit zero-page base address referred to in the single-byte operand.
- Any ZP,X or (ZP,X) instruction is useful in a ZP data stack,
where X is used as the stack pointer.
- Any abs,X (as well as abs,Y ) instruction is useful in non-ZP data
stacks as mentioned 90% of the way down the page in section 4 which introduces virtual stacks.
- There's no JMP (ZP,X) instruction, but you can use JMP (abs,X)
with the high operand byte as 00. Jump to the address pointed to by the cell at the top of the data
stack. (Don't forget to drop that cell later, by incrementing X twice.)
Just to whet your appetite: The 65816 further adds the following. Remember also that the '816 has a 16-bit stack pointer,
and its direct page (ie, DP) is not glued to page 0 like the 6502's is, but it can start anywhere in the first 64K of the memory map. One
implication is that you can position the direct page and the stack pointer S to both access the same area for some techniques.
JSR (abs,X) $FC New addressing mode, like 65c02's JMP (abs,X)
JSL long $22 Jump to subroutine, long, ie, 24-bit addr. (4-byte instruction, having a 3-byte operand)
RTL $6B Return from subroutine, long (ie, 24-bit return addr).
LDA [DP],Y [*] Similar to the 6502's LDA(ZP),Y but the base address read from DP is 24-bit (3 bytes, not 2).
LDA sr,S [*] sr=stack-relative. Hardware-stack pointer S plus unsigned 8-bit operand gives effective addr.
LDA (sr,S),Y [*] Adds the operand to the hardware-stack pointer, and reads the contents of the resulting addr.
Then it adds Y to get the final effective address to read or write.
PEA $F4 Pushes the operand itself onto the hardware stack. ‾⌉ PEA, PEI, and PER don't effect µP
PEI $D4 Reads addr pointed to by operand, and pushes result. | registers. Operands are always
PER $62 Takes operand minus current addr, and pushes result._⌋ 16-bit, and they always push 2 bytes.
TCS $1B Like TXS, but transfers A to stack pointer, w/o disturbing X.‾⌉ These four are always 16-
TSC $3B Like TSX, but transfers stack pointer to A, w/o disturbing X. | bit, regardless of M flag.
TCD $5B Transfer A to direct-page pointer register. | (Hence the "C" in the
TDC $7B Transfer direct-page pointer register to A. _⌋ mnemonic instead of "A".)
TXY $9B Transfer X directly to Y, without affecting A.‾⌉ These two are listed because X and Y are
TYX $BB Transfer Y directly to X, without affecting A._⌋ frequently used as virtual-stack pointers.
PHB $8B Push the data-bank register onto the hardware stack.
PHD $0B Push the direct-page register onto the hardware stack.
PHK $4B Push the program-bank register onto the hardware stack.
PLB $AB Pull the data-bank register off the hardware stack.
PLD $2B Pull the direct-page register off the hardware stack.
REP $C2 See notes. For changing status bits w/o SE_/CL_ instructions, even multiple bits at a time.
SEP $E2 See notes. For changing status bits w/o SE_/CL_ instructions, even multiple bits at a time.
(There are more, but these are the ones relevant to stacks.)
In section 13, we will look into ways to synthesize the 65816's PEA, PEI, and PER instructions on a 6502.
- [*] [DP],Y, sr,S, and (sr,S),Y addressing modes
also apply to ADC, AND, CMP, EOR, ORA, SBC, and STA. 24 op
codes. These are immensely useful for dealing with stack frames, which we'll be discussing in section 14, on local variables.
- Although the 6502 has PHP and PLP, the '816 adds the M and X bits to P, making
P a full 8 bits. If M is clear, A and memory accesses are 16-bit; otherwise they are 8-bit. If X is clear, X and Y
and their related memory accesses are 16-bit; otherwise they are 8-bit.
- TSX and TXS are 16-bit if the X flag is clear, ie, if index registers are in
16-bit mode. In the case of TXS with X flag set, the high byte of S is zeroed. Note that this
does not match up to the 6502 whose hardware stack page is always 1; but for the '816 in its native mode, page 1 has no special
significance for the stack. It is no different from other pages. This was discussed
on the 6502.org forum.
- REP and SEP are two-byte instructions for clearing and setting selected
bits (potentially several at a time) in the processor status register P according to a mask in the operand. The 6502 has a
not-quite-complete set of SE_/CL_ instructions for the bits it does have
(which is two less than the '816 has). It can handle the others with a poor synthesis of the 65816's REP
and SEP by pushing P onto the stack (either with an interrupt or PHP),
then using PLA to pull it into A for ANDing or ORing,
then pushing the result back onto the stack with PHA, then pulling it back into P (either
with RTI or PLP).
9. RPN efficiency <--Previous |
Next--> 11. synth instructions w/ RTS
last updated Jan 30, 2016