EEE8087 1W Rev. 1.3 Real Time Embedded Systems Worksheet 1.
Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit
EEE8087 1W Rev. 1.3
Real Time Embedded Systems
Worksheet 1. Assembly Language Familiarisation Exercises
The processor we are using in the lab is the Freescale Coldfire+, which is a derivative of the 68000. The simulator can be downloaded from www.easy68k.com. It is more advanced than the generic device used to introduce the ideas in the lecture. Its main features are summarised below.
Wordlength
The simple processor used in the lecture carried out operations on 8-bit data values. By default, the 68000 processor works on 16-bit values, although it can be set to use 8 or 32-bit values if desired. For now, we will work at 16 bits. Therefore, any data value occupies two consecutive byte locations in memory. For example, an item of data at address 3000 (hex) actually occupies addresses 3000H and 3001H.
Specification of hexadecimal values
By default the assembler for this processor assumes that all numbers are in decimal. To specify a hexadecimal number, it must be prefixed with '$'. E.g. 4000H would be written $4000.
Registers
This processor has 8 registers, called 'data registers', numbered D0 .. D7, e.g.
add $1000,d1 Add the 16-bit value in memory location 1000H - 1001H to D1, leaving the result in D1.
Operand locations
An instruction can act on values held in:
a register and a memory location, e.g.
sub $1000,d0 Subtracts the 16-bit value in memory location 1000H - 1001H from the value in D0, leaving the result in D0.
two registers, e.g.
move d2,d3 Moves the 16-bit value in D2 to D3.
a constant value and a register: the constant is denoted by '#', e.g.
move #2,d4 Moves the value 2, not the value held in memory location 2, to D4.
add #$000A,d5 Adds the hexadecimal value 0AH (decimal 10) to D5.
The result should always be returned to a register, so the right-hand operand is always D0 .. D7. The only exception is with a move instruction, e.g.
move d1,$2000 Moves the 16-bit value in D1 to memory location 2000H - 2001H.
Flags
A zero flag is set true if an instruction returns a zero result, or false if not. There are a few other flags that will be introduced as they are needed.
Instructions
The most commonly used instructions are listed here, with examples of their use.
move |
$2000,d0 |
Moves the contents of a 16-bit value from memory locations 2000H - 2001H into data register D0. Sets zero flag true if the value moved is zero; if not then sets it false. |
add |
$200A,d1 |
Adds the 16-bit value from locations 200AH - 200BH into D1. Sets the zero flag to true if the result of the addition is zero, otherwise sets it false. |
sub |
d2,d3 |
Subtracts the 16-bit value in D2 from the value in D3, leaving the result in D3. Sets zero flag true if the result is zero, or false if not. |
beq |
name |
'Branch if equal': Goes to another instruction if the zero flag was set true by the previous instruction. The instruction branched to is identified by the name given in the instruction. If the zero flag was left at false by the previous instruction, then the instruction does nothing and control passes to the next instruction in sequence. |
bne |
name |
'Branch if not equal': Behaves as BEQ except that the logic is reversed. It branches if the zero flag was not true, that is, if it was false, and does nothing if it was true. |
bra |
name |
Branches to the named instruction unconditionally. |
There are two instructions for defining storage.
name |
ds |
1 |
Defines memory for one 16-bit value and gives it the name specified. The assembler will allocate the actual memory location. E.g. |
x |
ds |
1 |
Define storage for a 16-bit value, and call it x. |
name |
dc |
value |
Define 16-bit constant, and give it the name and value shown. E.g. |
k6 |
dc |
6 |
Define a 16-bit constant with the value 6, and call it k6. |
Other instructions will be introduced in the questions as they are needed.
Note, in all cases, that instructions should be laid out in such a way that column 1 at the far left is only used for the name of an instruction or data item.
Address Registers
There are also 8 address registers, numbered A0 .. A7. These allow the address on which an instruction acts to be computed and changed during the execution of the programme, instead of being fixed in the instruction code. E.g.
move $1000,a0 Loads address 1000H into A0
move (a0), d0 Moves 16 bits from memory location addressed by A0 (1000H) to D0
add #2,a0 Adds 2 to A0, which becomes 1002H
move (a0),d1 Moves 16 bits from location 1002H to D1
The address registers may also be used in offset addressing, e.g. to access different elements in a data structure. Suppose that there is an array of data records. The array is called recary, and each record within it is called rec. Each record contains three elements: item1, item 2 and item3. Each element is 2 bytes long, so each record is 6 bytes.
recary |
|||||
rec [0] |
rec [1] |
||||
item 1 |
item 2 |
item 3 |
item 1 |
item 2 |
item 3 |
0 2 4 0 2 4
Storage is defined for 8 records:
recary ds 24 Define storage for 24 (8 x 3) 16-bit values
The record itself is defined as follows, using 'equate' directives that assign the value to the name. (There are better ways to do this, but this is the most straightforward).
rec |
equ |
0 |
record |
item1 |
equ |
0 |
item 1 is located at the start of the record (i.e. zero bytes from it) |
item2 |
equ |
2 |
item 2 is located 2 bytes from the start |
item3 |
equ |
4 |
item 3 is located 4 bytes from the start |
reclen |
equ |
6 |
the length of the record is 6 bytes |
We place the address of the array in A0. A0 now 'points' to the first record, rec [0].
move #recary,a0 move the value recary (i.e. the address of recary) to A0
recary |
|||||
rec [0] |
rec [1] |
||||
item 1 |
item 2 |
item 3 |
item 1 |
item 2 |
item 3 |
0 2 4 0 2 4
A0 |
Elements within it may then be addressed as follows.
move item1(a0),d0 move item1 (in the memory location at 0 bytes from A0) into D0
move item2(a0),d1 move item2 (2 bytes from A0) into D1
move item3(a0),d2 move item3 (4 bytes from A0) into D2
If we now increase the value in A0 by the record length reclen, which was defined as 6, A0 will now contain the address of the next record, rec [1]. The three instructions above will then access data from the second record in the array.
add #reclen, a0
recary |
|||||
rec [0] |
rec [1] |
||||
item 1 |
item 2 |
item 3 |
item 1 |
item 2 |
item 3 |
0 2 4 0 2 4
A0 |
2024-01-18
Assembly Language Familiarisation Exercises