Code_ The Hidden Language of Computer Hardware and Software - Charles Petzold [82]
The computer that we've built is constructed from relays, wires, switches, and lightbulbs. All of these things are hardware. In contrast, the instructions and other numbers that we enter into memory are called software. It's "soft" because it can be changed much more easily than the hardware can.
When we speak of computers, the word software is almost synonymous with the term computer program, or, more simply, program. Writing software is known as computer programming. Computer programming is what I was doing when I determined the series of instructions that would allow our computer to multiply two numbers together.
Generally, in computer programs, we can distinquish between code (which refers to the instructions themselves) and data, which are the numbers that the code manipulates. Sometimes the distinction isn't so obvious, as when the Halt instruction served double duty as the number –1.
Computer programming is sometimes also referred to as writing code, or coding, as in, "I spent my vacation coding" or "I was up until seven this morning banging out some code." Sometimes computer programmers are known as coders, although some might consider this a derogatory term. Such programmers might prefer to be called software engineers.
The operation codes that a processor responds to (such as 10h and 11h for Load and Store) are known as machine codes, or machine language. The term language is used because it's akin to a spoken or written human language in that a machine "understands" it and responds to it.
I've been referring to the instructions that our machine carries out by rather long phrases, such as Add with Carry. Commonly, machine codes are assigned short mnemonics that are written with uppercase letters.
These mnemonics can be as short as 2 or 3 letters. Here's a set of possible mnemonics for the machine codes that our computer recognizes:
Operation
Code
Mnemonic
Load
10h
LOD
Store
11h
STO
Add
20h
ADD
Subtract
21h
SUB
Add with Carry
22h
ADC
Subtract with Borrow
23h
SBB
Jump
30h
JMP
Jump If Zero
31h
JZ
Jump If Carry
32h
JC
Jump If Not Zero
33h
JNZ
Jump If Not Carry
34h
JNC
Halt
FFh
HLT
These mnemonics are particularly useful when combined with a couple of other shortcuts. For example, instead of saying something long-winded like, "Load byte at address 1003h into accumulator," we can instead write the statement:
LOD A,[1003h]
The A and the [1003] that appear to the right of the mnemonic are called arguments that indicate what's going on with this particular Load instruction. The arguments are written with a destination on the left (the A stands for accumulator) and a source on the right. The brackets indicate that the accumulator should be loaded not with the value 1003h but with the value stored in memory at address 1003h.
Similarly, the instruction "Add byte at address 001Eh to accumulator" can be shortened to
ADD A,[001Eh]
and "Store contents of accumulator at address 1003h" is
STO [1003h],A
Notice that the destination (a memory location for the Store instruction) is still on the left and the source is on the right. The contents of the accumulator must be stored in memory at address 1003h. The wordy "Jump to 0000h if the Zero flag is not 1" is more concisely written as
JNZ 0000h
The brackets aren't used in this instruction because the instruction jumps to address 0000h, not to the value that might be stored at address 0000h.
It's convenient to write these instructions in this type of shorthand because the instructions can be listed sequentially in a readable way that doesn't require us to draw boxes of memory locations. To indicate that a particular instruction is stored at a particular address, you can use the hexadecimal address followed by a