Code_ The Hidden Language of Computer Hardware and Software - Charles Petzold [107]
These two instructions load the Program Counter or the Stack Pointer from the register pair HL:
Opcode
Instruction
Meaning
E9h
PCHL PC,HL
Load Program Counter from HL
F9h
SPHL SP,HL
Load Stack Pointer from HL
The PCHL instruction is actually a type of Jump. The next instruction that the 8080 executes is the one located at the address stored in the HL register pair. SPHL is another method to set the Stack Pointer.
These two instructions exchange the contents of HL first with the two bytes located on top of the stack and second with the register pair DE:
Opcode
Instruction
Meaning
E3h
XTHL HL,[SP]
Exchange top of stack with HL
EBh
XCHG HL,DE
Exchange DE and HL
I haven't described the 8080 Jump instructions yet, except for PCHL. As you'll recall from Chapter 17, a processor includes a register called the Program Counter that contains the memory address the processor uses to retrieve the instructions that it executes. Normally the Program Counter causes the processor to execute instructions that are located sequentially in memory. But some instructions—usually named Jump or Branch or Goto—cause the processor to deviate from this steady course. Such instructions cause the Program Counter to be loaded with another value. The next instruction that the processor fetches is somewhere else in memory.
While a plain old ordinary Jump instruction is certainly useful, conditional jumps are even better. These instructions cause the processor to jump to another address based on the setting of a particular flag, such as the Carry flag or the Zero flag. The presence of a conditional Jump instruction is what turned the Chapter 17 automated adding machine into a general-purpose digital computer.
The 8080 has five flags, four of which are used for conditional jumps. The 8080 supports nine different Jump instructions, including the unconditional Jump and conditional jumps based on whether the Zero, Carry, Parity, and Sign flags are 1 or 0.
Before I show these instructions to you, however, I want to introduce two other types of instructions that are related to the Jump. The first is the Call instruction. A Call is similar to a Jump except that prior to loading the Program Counter with a new address, the processor saves the previous address. Where does it save that address? Why, on the stack, of course!
This strategy means that the Call instruction effectively saves a reminder of where it jumped from. The saved address allows the processor to eventually return to the original location. The returning instruction is called, appropriately, Return. The Return instruction pops 2 bytes from the stack and loads the Program Counter with that value.
The Call and Return instructions are extremely important features of any processor. They allow a programmer to implement subroutines, which are snippets of frequently used code. (By frequently I generally mean more than once.) Subroutines are the primary organizational elements of assembly-language programs.
Let's look at an example. Suppose you're writing an assembly-language program and you come to a point where you need to multiply 2 bytes. So you write some code that does precisely that, and you continue with the program. Now you come to another point where you need to multiply 2 bytes. Well, you already know how to multiply two numbers, so you can simply use the same instructions all over again. But do you simply enter the instructions into memory a second time? I hope not. It's a waste of time and memory. What you'd rather do is just jump to the previous code. But the normal Jump doesn't work either because there's no way to return to the current place in the program. That's what the Call and Return instructions let you do.
A group of instructions that multiply 2 bytes is an ideal candidate for a subroutine. Let's take a look at such a subroutine. In Chapter 17, the bytes to be multiplied (and the result) were stored in particular locations in memory. This 8080 subroutine instead multiplies the byte in register