Microprocessors Lecture 3

Instruction Length

So far we have assumed that instructions are all the same number of bits and it was suggested that this instruction length is 8 bits. This is in fact not the case because an 8 bit length imposes tremendous restrictions on the number of instructions available and doesn't take into account the need for many instructions to include an address.

Take for example the instruction 'Load accumulator A with the contents of memory location $2A01'. The instruction code has to contain information about the type of instruction 'Load accumulator', which register is involved 'Accumulator A' and the address from which data is to be fetched 'Memory location 2A01'.

There is no way that all this can be coded in 8 bits, although there are some tricks as we shall see for condensing the length of instructions. The only solution is to make the instruction longer so that we have an 8 bit code meaning 'Load accumulator A with the contents of memory register' (B6 for the 6809 - I shall use hex notation but remember it is only a short-hand for a binary code) and then specify which memory register by including the address in full in two further instruction words. Thus we have a three byte instruction in three consecutive memory locations.

                           memory location n      - B6
                                           n+1    - 2A
                                           n+2    - 01
On the other hand some instructions can be fitted into a single byte; usually where no reference to a memory address is required. For example 'Decrement Acc A'. This has the single byte instruction code 4A.

Instructions, therefore, are variable in length and included in the first byte must be information about how many bytes are in the instruction. In other words 4A is always a single byte instruction and B6 is always a 3 byte instruction. In the 6809 instructions can be 1,2,3 or 4 bytes in length. We have seen how 1 and 3 byte ones come about. Two byte instructions result from using a shortened version of the address or include 8 bit data in the instruction e.g. 'Load Acc A with the number FF'

                           memory location n      - 86
                                           n+1    - FF
Four byte instructions are really illogical and result largely from the fact that when Motorola designed the 6809 they wanted it to be compatible with previous processors the 6800 and 6802. These had fewer instructions (no general transfer instruction and fewer indexing modes for example) and fewer registers (no Index register Y and no Stack pointer U and no D register). Nevertheless the vast majority of the 256 different instruction codes had already been used. To allow the extra instructions and in particular those to handle the extra registers they used the few unused codes to access an extended set of instructions (e.g. 1E, 10 & 11). Thus the instruction 'Load Index register Y with the number $FE00' is -
                          memory location n      - 10
                                          n+1    - 8E
                                          n+2    - FE
                                          n+3    - 00
This problem of maintaining compatibility with ealier processors is a very serious one. As a microprocessor manufacturer you cannot expect your users to rewrite all their software when you bring out a new processor. There are two alternative approaches.
  1. You make any new processor include all the instruction codes of the old one and use tricks (such as that above) to access new instructions.
  2. You provide software which will convert software written for the old processor so that it will run on the new one. This means you have to make sure that there are instructions (or sequences of instructions which will exactly imitate the old ones). This can result in some very inefficient programs and users expecting greater speed as a result of improved processor performance are often disappointed.
Intel have always followed the first route and this has resulted in the instruction sets for its processors being highly idiosyncratic and illogical. For example the very first 8 bit processor, the 8008 had a very limited instruction set and no instructions to access memory in the way I described ealier. Instead it had two 8 bit registers H and L which had to be loaded first. So the operation above requires 3 instructions.
                    Load H with 2A
                    Load L with 01
                    Load Acc from memory
Even processors such as the 80486 retain H and L registers and the instructions for using them in this way!

Motorola retained compatibility in its range of 8 bit processors but when it brought out the 16 bit processor, 68000 some years ago it dropped all attempt at compatibility and tried to design a logical processor and instruction format.

Addressing Modes

As we have seen many instructions require that locations in the bank of memory registers be defined in some way. This is particularly true of data movement instructions 'Load Acc B with contents of location A02B' etc. The way in which the appropriate memory locations are defined is known as an addressing mode.

Many of the instructions in most processors can be used with a variety of addressing modes. Generally the more sophisticated the processor the greater the number of these modes. There are six main addressing modes in the 6809:-

Many of the data movement instructions can use all of these modes whilst others such as branch instructions can only use a few.

Immediate Addressing

This mode is the simplest - but at the same time seems to cause the most confusion. It is used when the required data is fixed and is known at the time of writing the program. E.g. 'Load Acc A with $FF'. Every time the program is run the data is the same 'FF' and the value is known at the time of writing the program - it might be used to initialise an interface register for example. Since the data is known and fixed it can be conveniently stored as part of the program (in ROM if the program is in ROM) without using up additional memory registers. This instruction would be coded as:-
                   Load Acc A with FF     LDA  #$FF        86
Sometimes people say 'There isn't any address specified so its not really an addressing mode at all'. This is not really correct - the address of the data is the location following the instruction and in order to get the data the processor has to output the address contained in the program counter on the address bus and read the data that comes back on the data bus into the appropriate register. So although no address is specified in the instruction, there is an address and it can be deduced by the processor from the address of the instruction itself. It is really a special case of relative addressing which we shall look at later.

The processor will automatically read the correct number of bytes of data for the size of register into which data is being transferred. The accumulators are 8 bits and require one byte of data but the index registers are 16 bits and so require two bytes. e.g.

                   Load IR X with 2000    LDX #$2000       8E
This is an important point to remember and which which often catches you out in the lab. If you forget to supply two bytes the processor can't detect this, it will just take the next byte which you intend to be an instruction and put it into the IR. The processor is then out of step with your instructions which can have disastrous effects.

Direct Addressing

This section is included for completeness. It is not essential for the course and you are advised to avoid the Direct Addressing mode and to use Extended Addressing instead.

This name is a little confusing because it is not very direct at all - but Motorola call it this so we will have to stick with it.

The purpose of this mode is to allow an address to be specified using only 8 bits rather than 16. This leads not only to shorter instructions and shorter programs but also faster instructions because the extra byte does not have to fetched from memory. The way it works is that the address byte specified in the program is the least significant byte. The most significant byte is supplied by the DP or Direct Page register in the processor. Suppose in our program we are going to access a lot of data in the range FE00 to FE10, then we could load DP with FE and then use direct addressing throughout. Unfortunately there is no instruction for loading DP easily, we have to load A or B with the appropriate value and transfer it into DP-

                    Load A with FE     LDA  #$FE       86
                    Transfer A to DP   TFR A,DP        1F
Then if we want to load A from location FE00 we can say
                    Load A from DP+0   LDA  <$00       96
or if we want to store B in FE01
                    Store B in DP+01   STB  <$01       D7
So once we have loaded DP with the appropriate page value or base value we can easily refer to addresses within that page of 256 memory locations.

This is an example of Effective Address calculation. The processor does not use the address part of the instruction immediately, it calculates the address by taking the DP value, shifting it right 8 places and then adding the address given in the instruction. This is a useful term and we will come across it quite a lot in future.

Extended Addressing

This is in fact far more straight-forward than direct addressing. The whole address is given in the instruction as a two-byte value following the instruction code. The advantage over direct addressing is that any location can be specified, its disadvantages are that it takes an extra byte and extra clock cycles to be carried out.
                    Store B in FE01    STB  $FE01     F7

                    Load IRX from 102B LDX $102B      BE
Note with this last example, since IRX is a 16 bit register two bytes of data are needed. These are taken from 102B AND 102C which are copied into the high and low bytes of X respectively.

Selected 6809 Instructions

Some typical instructions are given below. These are in the following format:
| instruction description | mnemonic | op-code |
Where the instruction description refers to M (e.g. A=A+M) this always refers to the contents of the effective address (EA) of the data.

The mnemonic given is the basic one; if you want to distinguish between immediate data and an address, then you will have to add a hash (#) after the mnemonic to indicate immediate data.

Most of the op-codes given are single bytes. The two (or four) letters after the op-code (e.g. dd) are to help you decide how many bytes of data are required, and whether this is data (dd), address (mm/nn) or an offset (bb).

	dd	indicates a byte of immediate data
	mm nn	are two bytes of a full address
	nn	is the low byte, used in direct addressing
	bb	is a 2's complement offset to PC which allows the program to branch
	++	is the postbyte (and offset) for indexed mode

(+ bytes)
Immediate Extended Indexed Inherent Relative
Add with carry
ADCA 89 dd B9 mm nn A9 ++    
ADDA 8B dd BB mm nn AB ++    
ADDB CB dd FB mm nn EB ++    
ANDA 84 dd B4 mm nn A4 ++    
Clear accumulator
CLRA       4F  
Clear accumulator
CLRB       5F  
(A-M) set flags
CMPA 81 dd B1 mm nn A1 ++    
ORA 8A dd BA mm nn AA ++    
Load accumulator
LDA 86 dd B6 mm nn A6 ++    
Store accumulator
STA   B7 mm nn A7 ++    
Load double accumulator
LDD CC dd dd FC mm nn EC ++    
Store double accumulator
STD   FD mm nn EC ++    
Load X register
LDX 8E dd dd BE mm nn AE ++    
Branch if zero
flag Z=1
BEQ         27 bb
Branch if not zero
flag Z=0
BNE         26 bb
Branch if minus
flag N=1
BMI         2B bb
JMP   7E mm nn      
Software Interrupt
End program
SWI      3F  
No operation
NOP       12  
Increment Memory
INC   7C mm nn 6C ++    
Decrement Memory
DEC   7A mm nn 6A ++    

| Back | Next |