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