Code_ The Hidden Language of Computer Hardware and Software - Charles Petzold [106]
Opcode
Instruction
Opcode
Instruction
C5
PUSH BC
C1
POP BC
D5
PUSH DE
D1
POP DE
E5
PUSH HL
E1
POP HL
F5
PUSH PSW
F1
POP PSW
The PUSH BC instruction stores registers B and C on the stack, and POP BC retrieves them. The abbreviation PSW in the last row refers to the Program Status Word, which, as you'll recall, is the 8-bit register that contains the flags. The two instructions in the bottom row actually push and pop both the accumulator and the PSW. If you want to save the contents of all the registers and flags, you can use
PUSH PSW
PUSH BC
PUSH DE
PUSH HL
When you later need to restore the contents of these registers, use the POP instructions in reverse order:
POP HL
POP DE
POP BC
POP PSW
How does the stack work? Let's assume the Stack Pointer is 8000h. The PUSH BC instruction causes the following to occur:
The Stack Pointer is decremented to 7FFFh.
The contents of register B are stored at the Stack Pointer address, or 7FFFh.
The Stack Pointer is decremented to 7FFEh.
The contents of register C are stored at the Stack Pointer address, or 7FFEh.
A POP BC instruction executed when the Stack Pointer is still 7FFEh undoes everything:
The contents of register C are loaded from the Stack Pointer address, or 7FFEh.
The Stack Pointer is incremented to 7FFFh.
The contents of register B are loaded from the Stack Pointer address, or 7FFFh.
The Stack Pointer is incremented to 8000h.
For every PUSH instruction, the stack increases 2 bytes in size. It's possible—possibly due to a bug in a program—that the stack will get so big that it will begin to overwrite some code or data needed by a program. This is a problem known as stack overflow. Similarly, too many POP instructions can prematurely exhaust the contents of the stack, a condition known as stack underflow.
If you have 64 KB of memory connected to your 8080, you might want to initially set the Stack Pointer to 0000h. The first PUSH instruction decrements that address to FFFFh. The stack then occupies the area of memory with the very highest addresses, quite a distance from your programs, which will probably be in the area of memory starting at address 0000h.
The instruction to set the value of the stack register is LXI, which stands for Load Extended Immediate. These instructions also load 16-bit register pairs with the two bytes that follow the opcode:
Opcode
Instruction
01
LXI BC,xxxx
11
LXI DE,xxxx
21
LXI HL,xxxx
31
LXI SP,xxxx
The instruction
LXI BC,527Ah
is equivalent to
MVI B,52
MVI C,7Ah
The LXI instruction saves a byte. In addition, the last LXI instruction in the preceding table is used to set the Stack Pointer to a particular value. It's not uncommon for this instruction to be one of the first instructions that a microprocessor executes after being restarted:
0000h: LXI SP,0000h
It's also possible to increment and decrement register pairs and the Stack Pointer as if they were 16-bit registers:
Opcode
Instruction
Opcode
Instruction
03
INX BC
0B
DCX BC
13
INX DE
1B
DCX DE
23
INX HL
2B
DCX HL
33
INX SP
3B
DCX SP
While I'm on the subject of 16-bit instructions, let's look at a few more. The following instructions add the contents of 16-bit register pairs to the register pair HL:
Opcode
Instruction
09
DAD HL,BC
19
DAD HL,DE
29
DAD HL,HL
39
DAD HL,SP
These instructions could save a few bytes. For example, the first of these instructions would normally require 6 bytes:
MOV A,L
ADD A,C
MOV L,A
MOV A,H
ADC A,B
MOV H,A
The DAD instruction is normally used for calculating memory addresses. The only flag that the instruction affects is the Carry flag.
Next let's look at some miscellaneous instructions. These two opcodes are followed by a 2-byte address and store and load the contents of the register pair HL at that address:
Opcode
Instruction
Meaning
2h
SHLD [aaaa],HL
Store HL Direct
2Ah
LHLD HL,[aaaa]
Load HL Direct
The L register is stored at address