Week 14Instruction Set

Outcomes

·  Further practice of using the AVR instruction set.

·  Use further instructions to change the flow of program.

·  To reinforce understanding of the basis of computer architectures.

The computer is told what to do by giving it instructions. These instructions are binary codes which the machine understands because it has been designed to do so. The complete set of instructions that the microprocessor understands is known as the instruction set. As a programmer it is convenient to represent the instruction using what is known as an assembly language, which consists of simple 3-letter mnemonics (sometimes 4-letter) that correspond to the machine codes.

1. Recap

The instruction to load a register with a value may look something like this

ldi r30,0xaa

This would be read as "load the hex value ‘aa’ into register r30". The 0x indicates that this is a hexadecimal value.

Addition would be done with an instruction like:

add r28, r29

This would be read as "add the value in register r29 to the value in r29 and write the result to r28". r28 is known as the destination register. This is an example of a 1 byte instruction.

Warning Processors other than the AVR may add the two values together and leave the result in the second named register.

ldi r30,0xaa

This instruction is an example of a 2 byte instruction - the first byte is a code corresponding to the instruction ldi, and the second byte containing the value ‘aa’.

Task 1

Write a program to add to numbers (100 and 28) together and put the result in register r16.

2. Changing the flow of the program

As well as telling the processor what to do, some instructions can alter the flow of the program. An example is the "jump" instruction which replaces the value in the program counter. So for example:

jmp 0x10

is an instruction to jump to address 10. In the example given in the previous learning package, if we placed the jmp 0x10 instruction at the end of the program, we would effectively set up a continuous loop so that the program would be repeated for ever. When the program counter gets to the address of the instruction jmp 10, the program counter would be loaded with the value 10, so the next instruction would be START again.

loop: jmp loop

This is exactly the same as the previous example except we let the assembler work out the address. i.e. if the address was the same then loop will equal 0x17 and can usually be seen in the assembler listing. This will become clear once you have written one or two programs.

We can now write the program from the previous section using this assembly language. Type in the program below

ldi r16, 0x03

ldi r17, 0x01

label:

add r16, r17

rjmp label ;jump to label label

Looking at the registers what does this program do?


Sometimes we want to go to a particular part of the program if a certain event has (or even has not) occurred. This we can do by checking the status register, this contains a number of bits called flags which are set to 1 if a particular condition occurs, otherwise they are set to 0. Figure 1 shows some of the flags that can be found.

Figure 1 The status register

Amongst the flags shown are Z for zero and S for sign. Every time the ALU performs an operation, the result effects the flags. For example, if the ALU performs the operation 8 + 3 = 11, the result is positive and not zero, so the flags S and Z are both 0. However, if it performed the operation 3 - 8 = -5, the S flag is set to 1.

The flags shown are:

C Carry flag = 1 if a carry or borrow was used;

Z Zero flag = 1 if result is zero;

N Negative flag = 1 if MSB of result is one. Why?

V Two’s complement overflow flag= 1 if two’s complement overflow occurred;

P Parity flag = 1 if result has an even number of 1s;

S Sign flag = 1 if the result is negative;

H Half carry flag. Same as carry flag but for the lower nibble;

T T bit

I Global interrupt enable

So let us look at an example instruction that uses this. The branch if the result is not equal to zero (brne). This tests if the last calculation resulting in a zero, if it does not then jump to the memory location (or label) included in the instruction. The condition is determined by the status registers Z flag if this is set (in other words a 1) then last calculation resulted in a zero.

Try the program on the next page, describe what it does, and what did you see happen. You will need to cycle through the program a two or three time to see it’s operation. Look at registers r16-r18 and the status register as in figure 3. (sub r16,r17 is subtract contents of r17 from r16).

ldi r16, 0x03

ldi r17, 0x01

first: sub r16, r17

brne first ;jump if not equal to label first

Figure 2

Figure 3 The status register when r16 resulted in a zero

We can also compare two numbers and use that to do something, this is again based on using the status register. As an example cp r18,r16 mean compare contents of r18 and r16, it does this by subtracting one from the other, when the result becomes zero, the zero flag is set.

Now try this program, describe what it does and what did you see. You will need to cycle through the program a two or three time to see it’s operation. Look at registers r16-r18 and the status register as in figure 3.

ldi r16, 0x03

ldi r17, 0x01

ldi r18,0x05

first:

add r16, r17

cp r18,r16

brne first ;jump if not equal to label first