Assemblers are available from many sources and all provide the necessary conversion from source code to object code. In addition, they may provide other features that will help us in the programming.
Syntax help
Syntax is the structure of statements in a language, whether it be English or a computer language. In English, most people would recognize something is incorrect about saying ‘He are going’ rather than ‘He is going’. This is an example of a syntax error.
As an example, If we mistyped the instruction LD A C as LD A V then the assembler would be unable to convert this to object code since it will not recognize the ‘V’ as a valid register. A real cheapie assembler may just stop or miss out this instruction. A somewhat better one may put a message on the screen saying ‘syntax error code not recognized’ and a very helpful one may suggest a likely cause of the trouble. It may say, ‘syntax error. Invalid register. Register name may only be A, B, C, D , E, H or L.’
Labels
Another facility offered by a good assembler is the label. A label is a word that can be used to represent an address while the program is being written.
You will recall that we have to instruct the microprocessor to stop at the end of a program otherwise it will go off following random instructions. One way of stopping the microprocessor is to give it something quite meaningless to do. Suppose you opened an envelope, and the message inside read ‘put the envelope on the desk, pick it up, open the envelope and obey the instructions’. So you open the envelope, read the instructions, put it on the desk, pick it up and read the instructions. So you open the envelope, read the instructions… and I’m sure you can guess the next bit. We, of course, would soon stop doing this because we would see that it is pointless. A microprocessor on the other hand has no memory of ever having seen the instruction before and will be quite happy to do it forever if required.
Every byte of a program is stored in a sequence of memory locations so if we started a program in address 0300H we may have got to the address 0950H when the stop instruction is required. The last line of the program was ‘jump to address 0950H’. The jump instruction tells the microprocessor to go to the address that follows, in this case 0950H, and perform the instruction to be found there. The microprocessor now finds itself in the endless loop shown in Figure 9.6. Once the microprocessor is in one of these loops it will run continuously until the power supply is switched off, or the reset pin is taken low, or one of the interrupt pins is activated.
Figure 9.6 One way of stopping a microprocessor
So where does the label come in?
Let’s imagine that we find that we have to add an extra byte at the start of the program. This will result in each byte being shifted one place down in the memory and the last line of the program actually starting at address 0951H rather than 0950H. When the program tells the microprocessor to jump to address 0950H it will no longer be in the little loop. The new contents of address 0950H may provide any random instruction and the whole program could crash. This problem, shown in Figure 9.7, will not be seen as a mistake by the assembler. Remember that the assembler is only checking for known codes, not sensible programs.
Figure 9.7 A late change to the program can ruin everything
If we type a word over the position where the memory address normally resides it will be recognized by the assembler as a label. That is a word which is equivalent to the address it replaced. If we use the same label anywhere else in the program it will be given the same value. The good thing about this is that if the program is changed and the addresses change, then the value of the label is changed automatically so the two ‘STOP’s in the last line will always have the same value and the loop will be safe from accidental destruction (Figure 9.8).
Figure 9.8 Labels to the rescue!
Once the assembler accepts the label, it can be used as often as we like in the program but remember that a label can only ever have one meaning within a single program. The choice of label is usually restricted to avoid clashing with words that have a special meaning to the assembler. Words that can do this are called ‘reserved’ words and usually include words such as jump, LD, ADD, HALT etc. The actual list is provided with the assembler program.
Remarks
Assemblers and all higher languages allow us to write remarks or notes to act as reminders but to be ignored by the assembler. To tell the assembler program not to attempt converting it to object code we precede the note by a semicolon or the word REM: or something similar.
The last line of our program, using the mnemonic JP for jump could be written as:
STOP JP STOP ;this will hold the microprocessor in a loop.
Being able to add remarks to a program makes it much easier for the program to be understood at a later date. At the time of coding, the program seems, to the programmer at least, a model of clarity. When the programmer is off sick and we have to take over, their strategy is not obvious at all. It is even more embarrassing if the program that we cannot understand is the one that we wrote ourselves a few weeks earlier. The moral of this story is to add notes even if it seems ridiculously obvious at the time.
Assembly and machine code are not portable. This means that they are designed to be used on a particular microprocessor and are generally not able to be used on another type. They also require the programmer to have knowledge of the internal layout or architecture of the microprocessor.
Despite the two problems of portability and architecture knowledge, assembly language has survived the onslaught of the new, modern ‘improved’ languages considered in the next chapter.
Why?
Assembly languages have two overriding advantages in the hands of a competent programmer (note the ‘competent’). A program written in Assembly is faster and is more compact, i.e. it takes less memory space to store it. Machine code and assembly languages are called procedural languages. This means that the program instructs the microprocessor to complete the first instruction, then start the next, then the next and so on until it has finished the job. This is just like a recipe.
Nearly all microprocessor-based systems are designed to operate in this way and it seems so obvious that it is difficult to think that there is any alternative – but there is, as we will see later.
In each case, choose the best option.
1 An assembler:
(a) converts assembly programs into machine code.
(b) is a type of microprocessor.
(c) converts object code into machine code.
(d) is essential for converting mnemonics into source code.
2 The data that follows the op code:
(a) is always present and consists of one or more bytes.