0% found this document useful (0 votes)
16 views

CSC218 Sequential Programming Note

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

CSC218 Sequential Programming Note

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 112

INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING 14

What you will learn


In this chapter you will learn:
1. binary numbers, and how they relate to computer hardware.
2. to convert to/from binary, decimal, and hexadecimal
3. binary character data representation in ASCII
4. integer numbers, which are represented in binary 2's complement format.
5. arithmetic operations for binary numbers
6. binary logic operations
7. the effect of context on data values in a computer.

Chapter 1 Introduction
One of the major goals of computer science is to use abstraction to insulate the users from how
the computer works. For instance, computers can interpret speech and use natural language
processing to allow novice users to perform some pretty amazing tasks. Even programming
languages are written to enhance the ability of the person writing the code to create and support
the program, and a goal of most modern languages is to be hardware agnostic.
Abstraction is a very positive goal, but at some level a computer is just a machine. While High
Level Languages (HLL) abstract and hide the underlying hardware, they must be translated into
assembly language to use the hardware. One of the goals of a computer science education is to
strip away these abstraction and make the workings of the computing machine clear. Without an
understanding of a computer as a machine, even the best programmer, system administrator,
support staff, etc., will have significant gaps in what they are able to accomplish. A basic
understanding of hardware is important to any computer professional.
Learning assembly language is different than learning a HLL. Assembly language is intended to
directly manipulate the hardware that a program is run on. It does not rely on the ability to abstract
behavior, instead giving the ability to specify exactly how the hardware is to work to the
programmer. Therefore it uses a very different vocabulary than a HLL. That vocabulary is not
composed of statements, variables and numbers but of operations, instructions, addresses, and bits.
In assembly it is important to remember that the actual hardware to be used only understands
binary values 0 and 1. To begin studying assembly, the reader must understand the basics of
binary and how it is used in assembly language programming. The chapter is written to help the
reader with the concepts of binary numbers.

Chapter 1. 1 Binary Numbers


Chapter 1.1. 1 Values for Binary Numbers
Many students will have had a class covering logic or Boolean algebra, where the binary values are
generally true(T) and false(F), and use special symbols such as "^" for AND and "˅" for OR. This
15 INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING

might be fine for mathematics and logic, but is hopelessly inadequate for the engineering task of
creating computer machines and languages.

To begin, the physical implementation of a binary value in a Central Processing Unit's (CPU) hardware,
called a bit, is implemented as a circuit called a flip-flop or latch. A flip-flop has a voltage of either 0
volts or a positive voltage (most computers use +5 volts, but many modern computers use
+3.3 volts, and any positive voltage is valid). If a flip-flop has a positive voltage it is called high or on
(true), and if it has 0 volts it is low or off (false). In addition hardware is made up of gates that which
can either be open (true) or closed (false). Finally the goal of a computer is to be able to work with
data that a person can understand. These numbers are always large, and hard to represent as a series of
true or false values. When the values become large, people work best with numbers, so the binary
number 0 is called false, and 1 is called true. Thus while computers work with binary, there are a
number of ways we can talk about that binary. If the discussion is about memory, the value is high, on,
or 1. When the purpose is to describe a gate, it is open/closed. If there is a logical operations values
can be true/false. The following table summarizes the binary value naming conventions.
T/F Number Switch Voltage Gate
F 0 Off Low Closed
T 1 On High Open
Table 1-1: Various names for binary values

In addition to the various names, engineers are more comfortable with real operators. This book
will follow the convention that "+" is an OR operator, "*" is an AND operator, and "!" (pronounced
bang) is a not operator.
Some students are uncomfortable with the ambiguity in the names for true and false. They often
feel that the way the binary values were presented in their mathematics classes (as true/false) is
the "correct" way to represent them. But keep in mind that this class is about implementing a
computer in hardware. There is no correct, or even more correct, way to discuss binary values.
How they will be referred to will depend on the way in which the value is being used.
Understanding a computer requires the individual to be adaptable to all of these ways of referring
to binary values. They will all be used in this text, though most of the time the binary values of 0
and 1 will be used.

Chapter 1.1. 2 Binary Whole Numbers


The numbering system that everyone learns in school is called decimal or base 10. This
numbering system is called decimal because it has 10 digits, [0..9]. Thus quantities up to 9 can
be easily referenced in this system by a single number.
Computers use switches that can be either on (1) or off(0), and so computers use the binary, or
base 2, numbering system. In binary, there are only two digits, 0 and 1. So values up to 1 can be
easily represented by a single digit. Having only the ability to represent 0 or 1 items is too limiting
to be useful. But then so are the 10 values which can be used in the decimal system.
The question is how does the decimal handle the problem of numbers greater than 9, and can binary
use the same idea?
In decimal when 1 is added to 9 the number 10 is created. The number 10 means that there is 1
group of ten numbers, and 0 one number. The number 11 is 1 group of 10 and 1 group of one.
INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING 16

When 99 is reached, we have 100, which is 1 group of hundred, 0 tens, and 0 ones. So the number
1,245 would be:
1,245 = 1*103 + 2*102 + 4*101+ 5*100
Base 2 can be handled in the same manner. The number 102 (base 2) is 1 group of two and 0
ones, or just 210 (base 10).1 Counting in base 2 is the same. To count in base 2, the numbers are
02, 12, 102, 112, 1002, 1012, 1102 1112, etc. Any number in base 2 can be converted to base 10
using this principal. Consider 1010112, which is:
1*25 + 0*24 + 1*23 + 0 *22 + 1*21 + 1*20 = 32 + 8 + 2 + 1 = 4310
In order to work with base 2 number, it is necessary to know the value of the powers of 2. The
following table gives the powers of 2 for the first 16 numbers (to 215). It is highly recommended
that students memorize at least the first 11 values of this table (to 210), as these will be used
frequently.

n 2n n 2n n 2n n 2n

0 1 4 16 8 256 12 4096

1 2 5 32 9 512 13 8192

2 4 6 64 10 1024 14 16348

3 8 7 126 11 2048 15 32768


Table 1-2: Values of 2n for n = 0...15

The first 11 powers of 2 are the most important because the values of 2n are named when n is a
decimal number evenly dividable by 10. For example 210 is 1 Kilo, 220 is 1 Meg, etc. The names
for these value of 2n are given in the following table. Using these names and the values of 2n from
0-9, it is possible to name all of the binary numbers easily as illustrated below. To find the value
of 216, we would write:
216 = 210*26= 1K * 64 = 64K

Older programmers will recognize this as the limit to the segment size on older PC's which could
only address 16 bits. Younger students will recognize the value of 232, which is:
232 = 230 * 22 = 1G * 4 = 4G
4M was the limit of memory available on more recent PC's with 32 bit addressing, though that
limit has been moved with the advent of 64 bit computers. The names for the various values of
2n are given in the following table.
210 Kilo 230 Giga 250 Penta
220 Mega 240 Tera 260 Exa

1
The old joke is that there are 10 types of people in the world, those who know binary and those who do not.
17 INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING

Table 1-3: Names for values of 2n, n = 10, 20, 30, 40, 50, 60

Chapter 1. 2 Converting Binary, Decimal, and Hex Numbers


Chapter 1.2. 1 Converting Binary to Decimal
Computers think in 0's and 1's, and when dealing with the internal workings of a computer
humans must adjust to the computer’s mindset. However, when the computer produces answers,
the humans that use them like to think in decimal. So it is often necessary for programmers to be
able to convert between what the computer wants to see (binary), and what the human end users
want to see (decimal). These next 3 sections will deal with how to convert binary to decimal, and
then give 2 ways to convert decimal to binary. Finally, it will give a section on a useful
representation for handling large binary numbers called hexadecimal.
To convert binary to decimal, it is only necessary to remember that each 0 or 1 in a binary number
represents the amount of that binary power of 2. For each binary power of 2, you have either 0
or 1 instance of that number. To see this, consider the binary number 10010102. This number has
1 * 26 + 0 * 25 + 0 * 24 + 1 * 23 + 0 * 22 + 1 * 21 + 0 * 20 = 64 + 8 + 2 = 7410. This can be
generalized into an easy way to do this conversion. To convert from binary to decimal put the 2n
value of each bit over the bits in the binary number and add the values which are 1, as in the
example below:
64 32 16 8 4 2 1
10010102 = 1 0 0 1 0 1 0 = 64 + 8 + 2 = 7410

Chapter 1.2. 2 Converting Decimal to Binary using Binary Powers


Two ways to convert decimal number to binary numbers are presented here. The first is easy to
explain, but harder to implement. The second is a cleaner algorithm, but why the algorithm works
is less intuitive.
The first way to convert a number from decimal to binary is to see if a power of 2 is present in
the number. For example, consider the number 433. We know that there is no 2 9 (512) value in
433, but there is one value of 28 (or 256). So in the 9th digit of the base 2 number we would put
a 1, and subtract that 256 from the value of 433.
433 - 256 = 177 28 27 26 25 24 23 22 21 20

1 - - - - - - - -

Next check if there is a 27 (128) value in the number. There is, so add that bit to our string and
subtract 128 from the result.
INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING 18

177 - 128 = 49 28 27 26 25 24 23 22 21 20

1 1 - - - - - - -

Now check for values of 26 (64). Since 64 > 49, put a zero in the 26 position and continue.

49 - 0 = 49 28 27 26 25 24 23 22 21 20

1 1 0 - - - - - -

Continuing this process for 25 (32), 24(16), 23(8), 22(4), 21(2), and 20(1) results in the final answer.
28 27 26 25 24 23 22 21 20

1 1 0 1 1 0 0 0 1

Thus 43310 = 1101100012. This result can be checked by converting the base 2 number back to base
10.

Chapter 1.2. 3 Converting Decimal to Binary using Division


While conceptually easy to understand, the method to convert decimal numbers to binary
numbers in Chapter 1.2.3 is not easy to implement as the starting and stopping conditions are
hard to define. There is a way to implement the conversion which results in a nicer algorithm.
The second way to convert a decimal number to binary is to do successive divisions by the
number 2. This is because if a number is divided and the remainder taken, the remainder is the
value of the 20 bit. Likewise if the result of step 1 is divided again by 2 (so essentially dividing
by 2*2 or 4), the reminder is the value of the 21 bit. This process is continued until the result of
the division is 0. The example below shows how this works.
Start with the number 433. 433 divided by 2 is 216 with a remainder of 1. So in step 1 the result
would have the first bit for the power of 2 set to one, as below:

433 / 2 = 216 r 1 28 27 26 25 24 23 22 21 20

- - - - - - - - 1
19 INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING

The number 216 is now divided by 2 to give 108, and the remainder, zero, placed in the second
bit.

216 / 2 = 108 r 0 28 27 26 25 24 23 22 21 20

- - - - - - - 0 1

The process continues to divide by 2, filling the remainder in each appropriate bit, until at last
the result is 0, as below.

28 27 26 25 24 23 22 21 20

1 1 0 1 1 0 0 0 1

Chapter 1.2. 4 Converting between binary and hexadecimal


One of the biggest problems with binary is that the numbers rapidly become very hard to read. This
is also true in decimal, where there is often a "," inserted between groupings of 103. So for example
1632134 is often written as 1,632,134, which is easier to read.
In binary, something similar is done. Most students are familiar with the term byte, which is 8
bits. But fewer know of a nybble, or 4 bits. 4 bits in binary can represent numbers between 0..15,
or 16 values. So values of 4 bits are collected together and create a base 16 number, called a
hexadecimal (or simply hex) number. To do this, 16 digits are needed, and arbitrarily the numbers
and letters 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, and F were chosen as the 16 digits. The binary
numbers corresponding to these 16 digit hex numbers are given in the table below (note, the
normal way to indicate a value is in hex is to write a 0x before it So decimal 10 would be 0xA).

Binary Hex Binary Hex Binary Hex Binary Hex


Number Digit Number Digit Number Digit Number Digit

0000 0x0 0001 0x 1 0010 0x 2 0011 0x 3

0100 0x 4 0101 0x 5 0110 0x 6 0111 0x 7

1000 0x 8 1001 0x 9 1010 0x A 1011 0x B

1100 0x C 1101 0x D 1110 0x E 1111 0x F


Table 1-4: Binary to Hexadecimal Conversion
INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING 20

The hex numbers can then be arranged in groups of 4 (or 32 bits) to make it easier to translate
from a 32 bit computer.
Note that hex numbers are normally only used to represent groupings of 4 binary digits.
Regardless of what the underlying binary values represent, hex will be used just to show what
the binary digits are. So in this text all hex values will be unsigned whole numbers.

Most students recognize that a decimal number can be extended by adding a 0 to the left of a decimal
number, which does not in any way change that number. For example 0043310 = 043310
= 43310. The same rule applies to binary. So the binary number 1101100012 = 0001101100012.

But why would anyone want to add extra zeros to the left of a number? Because to print out the
hex representation of a binary number, I need 4 binary digits to do it. The binary number
1101100012 only has 1 binary digit in the high order byte. So to convert this number to binary it
is necessary to pad it with left zeros, which have no effect on the number. Thus 1 10011 00012 =
0001 1011 00012= 0x1B1 in hex. Note that even the hex numbers are often paded with zeros, as
the hex number 0x1B1 is normally be written 0x01B1, to get groupings of 4 hex numbers (or 32
bits).
It is often the case where specific bits of a 32 bit number need to be set. This is most easily done
using a hex number. For instance, if a number is required where all of the bits except the right left
most (or 1) bit of a number is set, you can write the number in binary as:

111111111111111111111111111111102
A second option is to write the decimal value as: 429496729510
Finally the hex value can be written as 0xFFFFFFFE
In almost all cases where specific bits are being set, a hex representation of the number is the
easiest to understand and use.

Chapter 1. 3 Character Representation


All of the numbers used so far in this text have been binary whole numbers. While everything in
a computer is binary, and can be represented as a binary value, binary whole numbers do not
represent the universe of numbering systems that exists in computers. Two representations that
will be covered in the next two sections are character data and integer data.
Though computers deal use binary to represent data, humans usually deal with information as
symbolic alphabetic and numeric data. So to allow computers to handle user readable
alpha/numeric data, a system to encode characters as binary numbers was created. That system is
called American Standard Code for Information Interchange (ASCII)2. In ASCII all character are
represented by a number from 1 - 127, stored in 8 bits. The ASCII encodings are shown in the
following table.

2
ASCII is limited to just 127 characters, and is thus too limited for many applications that deal with
internationalization using multiple languages and alphabets. Representations, such as Unicode, have been developed
to handle these character sets, but are complex and not needed to understand MIPS Assembly. So this text will limit
all character representations to ASCII.
21 INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING

Table 1-5: ASCII Table

Using this table, it is possible to encode a string such as "Once" in ASCII characters as the
hexadecimal number 0x4F6E63653 (capital O = 0x4F, n = 0x6E, c = 0x53, e = 0x65 ).
Numbers as character data are also represented in ASCII. Note the number 13 is 0xD or 11012.
However the value of the character string "13" is 0x3133. When dealing with data, it is important
to remember what the data represents. Character numbers are represented using binary values, but
are very different from their binary numbers.
Finally, some of the interesting patterns in ASCII should be noted. All digits start with binary
digits 0011 0000. Thus 0 is 0x0011 0000, 1 is 00011 0000, etc. To convert a numeric character
digit to a number it is only necessary to subtract the character value of 0. For example, '0' - '0' =
0, '1' - '0' = 1, etc. This is the basis for an easy algorithm to convert numeric strings to numbers
which will be discussed in the problems.
Also note that all ASCII upper case letters start with the binary string 0010 0000, and are 1 offset
for each new character. So A is 0100 0001, B is 0100 0010, etc. Lower case letters start with the
binary string 0110 and are offset by 1 for each new character, so a is 0110 0001, b is 0110 0010,

3
By now it is hoped that the reader is convinced that hexadecimal is a generally preferred way to represent data in a
computer. The decimal value for this string would be 1,332,634,469 and the binary would be 0100 1111 0110 1110
0110 0011 0010 0101. Having taught for many year, however, I know old habits die hard with many students who
will struggle endlessly converting to decimal to avoid learning hex.
INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING 22

etc. Therefore, all upper case letters differ from their lower case counterpart by a 1 in the digit 0100.
This relationship between lower case and capital letters will be use to illustrate logical operations
later in this chapter.

Chapter 1. 4 Adding Binary Whole Numbers


Before moving on to how integer values are stored and used in a computer for calculations, how
to do addition of binary whole numbers needs to be covered.
When 2 one-bit binary numbers are added, the following results are possible: 02+02 = 02; 02+12 =
12; 12+02 = 12; and 12+12 = 102. This is just like decimal numbers. For example, 3+4=7, and the
result is still one digit. A problem occurs, however, when adding two decimal numbers where the
result is greater than the base of the number (for decimal, the base is 10). For example, 9+8. The
result cannot be represented in one digit, so a carry digit is created. The result of 9+8 is 7 with a
carry of 1. The carry of 1 is considered in the next digit, which is actually adding 3 digits (the two
addends, and the carry). So 39 + 28 = 67, where the 10's digit (4) is the result of the two addends
(3 and 2) and the carry (1).
The result of 12+12 = 102 in binary is analogous to the situation in base 10. The addition of 12+12
is 02 with a carry of 12, and there is a carry to the next digit of 12.
An illustration of binary addition is shown in the figure below.

Figure 1-1: Binary whole number addition

Here the first bit adds 12 +12, which yields a 02 in this bit and a carry bit of 12. The next bit now
has to add 12 +12 +12 (the extra one is the carry bit), which yields a 12 for this bit and a carry bit
of 12. If you follow the arithmetic through, you have 00112 (310) + 01112 (710) = 10102 (1010).

Chapter 1. 5 Integer Numbers (2's Complement)


Chapter 1.5. 1 What is an Integer
Using only positive whole numbers is too limiting for any valid calculation, and so the concept
of a binary negative number is needed. When negative values for the set of whole numbers are
included with the set of whole number (which are positive), the resulting set is called integer
numbers. Integers are non-fractional numbers which have positive and negative values.
23 INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING

When learning mathematics, negative numbers are represented using a sign magnitude format,
where a number has a sign (positive or negative), and a magnitude (or value). For example -3 is
3 units (it's magnitude) away from zero in the negative direction (it's sign). Likewise, +5 is 5 units
away from zero in a positive direction. Signed magnitude numbers are used in computers, but not
for integer values. For now, just realize that it is excessively complex to do arithmetic using
signed magnitude numbers. There is a much simpler way to do things called 2's complement. This
text will use the term integer and 2's complement number interchangeably.

Chapter 1.5. 2 2's complement operation and 2's complement format


Many students get confused and somehow believe that a 2's complement has something to do with
negative numbers, so this section will try to be as explicit here as possible. Realize that if someone
asks, "What is a 2's complement?", they are actually asking two very different questions. There is
a 2's complement operation which can be used to negate a number (e.g. translate 2 -> -2 or -5 ->
5). There is also a 2's complement representation (or format) of numbers which can be used to
represent integers, and those integers can be positive and negative whole numbers.

To reiterate, the 2's complement operation can convert negative numbers to the corresponding
positive values, or positive numbers to the corresponding negative values. The 2's complement
operation negates the existing number, making positive numbers negative and negative numbers
positive.
A 2's complement representation (or format) simply represents number, either positive or
negative. If you are ever asked if a 2's complement number is positive or negative, the only
appropriate answer is yes, a 2's complement number can be positive or negative.
The following sections will explain how to do a 2's complement operation, and how to use 2's
complement numbers. Being careful to understand the difference between a 2's complement
operation and 2's complement number will be a big help to the reader.

Chapter 1.5. 3 The 2's Complement Operation


A 2's complement operation is simply a way to calculate the negation of a 2's complement number.
It is important to realize that creating a 2's complement operation (or negation) is not as simple as
putting a minus sign in front of the number. A 2's complement operation requires two steps: 1 -
Inverting all of the bits in the number; and 2 - Adding 12 to the number.
Consider the number 001011002. The first step is to reverse all of the bits in the number (which will
be achieved with a bit-wise ! operation. Note that the ! operator is a unary operation, it only takes
one argument, not two.
! (001011002) = 110100112
Note that in the equation above the bits in the number have simply been reversed, with 0's becoming
1's, and 1's becoming 0's. This is also called a 1's complement, though in this text we will never use
a 1's complement number.
The second step adds a 12 to the number.
INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING 24

110100112
000000012
110101002.

Thus the result of a 2's complement operation on 001011002 is 110101002 , or negative 2's
complement value. This process is reversible, as the reader can easily show that the 2's
complement value of 110101002 is 001011002. Also note that both the negative and positive
values are in 2's complement representation.
While positive numbers will begin with a 0 in the left most position, and negative numbers will
begin with a 1 in the leftmost position, these are not just sign bits in the same sense as the signed
magnitude number, but part of the representation of the number. To understand this difference,
consider the case where the positive and negative numbers used above are to be represented in 16
bits, not 8 bits. The first number, which is positive, will extend the sign of the number, which is
0. As we all know, adding 0's to the left of a positive number does not change the number. So
001011002 would become 00000000001011002.
However, the negative value cannot extend 0 to the left. If for no other reason, this results in a 0
in the sign bit, and the negative number has been made positive. So to extend the negative number
110101002 to 16 bits requires that the sign bit, in this case 1, be extended. Thus 110101002
becomes 11111111110101002.
The left most (or high) bit in the number is normally referred to as a sign bit, a convention this
text will continue. But it is important to remember it is not a single bit that determines the sign
of the number, but a part of the 2's complement representation.

Chapter 1.5. 4 The 2's Complement (or Integer) Type


Because the 2's complement operation negates a number, many people believe that a 2's
complement number is negative. A better way to think about a 2's complement number is that is
a type. A type is an abstraction which has a range of values, and a set of operations. For a 2's
complement type, the range of values is all positive and negative whole numbers. For operations,
it has the normal arithmetic operations such as addition (+), subtraction (-), multiplication (*) ,
and division (/).
A type also needs an internal representation. In mathematics classes, numbers were always
abstract, theoretical entities, and assumed to be infinite. But a computer is not an abstract entity,
it is a physical implementation of a computing machine. Therefore, all numbers in a computer
must have a physical size for their internal representation. For integers, this size is often 8 (byte),
16(short), 32(integer), or 64(long) bits, though larger numbers of bits can be used to store the
numbers. Because the left most bit must be a 0 for positive, and 1 for negative, using a fixed size
also helps to identify easily if the number is positive or negative.

Because the range of the integer values is constrained to the 2n values (where n is the size of the
integer) that can be represented with 2's complement, about half of which are positive and half
are negative, roughly 2n-1 values of magnitude are possible. However, one value, zero, must be
accounted for, so there are 1 less positive numbers than negative numbers. So while 28 is 256, the
2's complement value of an 8-bit number runs from -128 ... 127.
25 INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING

Finally, as stated in the previous section, just like zeros can be added to the left of a positive number
without effecting its value, in 2's complement ones can be added to the left of a negative number
without effecting its value. For example:

00102 = 0000 00102 = 210


11102 = 1111 1110 2= -210
Adding leading zeros to a positive number, and leading ones to a negative number, is called sign
extension of a 2's complement number.

Chapter 1. 6 Integer Arithmetic


Chapter 1.6. 1 Integer Addition
Binary whole number addition was covered in chapter 1.4. Integer addition is similar to binary
whole number addition except that both positive and negative numbers must be considered. For
example, consider adding the two positive numbers 00102 (210) + 00112 (310) = 01012 (510).

Figure 1-2: Addition of two positive integers

Addition of mixed positive and negative numbers, and two negative numbers also works in the
same manner, as the following two examples show. The first adds 00102 (210) + 11012 (-310) =
11112 (-110), and the second adds 11102 (-210) + 11012 (-310) = 10112 (-510).

Figure 1-3: Addition of positive and negative integers


INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING 26

Figure 1-4: Addition of two negative integers

Because integers have fixed sizes, addition and subtraction can cause a problem known as integer
overflow. This happens which the two numbers which are being added are large positive or
negative values, and the combining of the values results in numbers too big to be store in the
integer.

Chapter 1.6. 2 Overflow of Integer Addition


Because integers have fixed sizes, addition and subtraction can cause a problem known as integer
overflow. This happens which the two numbers which are being added are large positive or
negative values, and the combining of the values results in numbers too big to be store in the
integer value.
For example, a 4 bit integer can store values from -8...7. So when 01002 (410) + 01012 (5) = 10012
(-7) are added using 4 bit integers the result is too large to store in the integer. When this happens,
the number changes sign and gives the wrong answer, as the following figure shows.

Figure 1-5: Addition with overflow

Attempting to algorithmically figure out if overflow occur is difficult. First if one number is
positive and the other is negative, overflow never occurs. If both numbers are positive or negative,
then if the sign of the sum is different than the sign of either of the inputs overflow has occurred.
27 INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING

There is a much easier way to figure out if overflow has occurred. If the carry in bit to the last digit
is the same as the carry out bit, then no overflow has occurred. If they are different, then overflow
has occurred. In figure 1.3 the carry in and carry out for the last bit are both 0, so there is no
overflow. Likewise, in figure 1.4 the carry in and carry out are both 1, so there was no overflow.
In figure 1.5 the carry in is 1 and the carry out is 0, so overflow has occurred.
This method also works for addition of negative numbers. Consider adding 11002 (-410) and
10112 (-510) = 01112 (710), shown in figure 1.6. Here the carry in is 0 and the carry out is 1, so
once again overflow has occurred.

Figure 1-6: Subtraction with overflow

Chapter 1.6. 3 Integer multiplication using bit shift operations


Multiplication and division of data values or variables involves hardware components in the
Arithmetic Logic Unit (ALU). In assembly these operations will be provided by the various forms
mul and div operators, and the hardware to implement them is beyond the scope of this book
and will not be covered. However, what is of interest in writing assembly is multiplication and
division by a constant.
The reason multiplication and division by a constant is covered is that these operations can be
provided by bit shift operations, and the bit shift operations are often faster to run than the
equivalent mul or div operation. Therefore, bit shift operations are often used in assembly to do
multiplication and division, and therefore it is important for assembly language programmers to
understand how this works.
First consider multiplication of a number by a power of 10 in base 10. In base 10, if a number is
multiplied by a power of 10 (10n, where n is the power of 10), it is sufficient to move the number
n places to the right filling in with 0's. For example, 15*1000 (or 15 * 103) = 15,000.
This same concept holds in binary. To multiply a binary number (e.g. 15, or 000011112) by 2,
the number is shifted to the left 1 digit (written as 1111<<1), yielding 000111102 or 30.
Likewise multiplying 000011112 by 8 is done by moving the number 3 spaces to the left
INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING 28

(000011112<<3), yielding 011110002, or 120. So it is easy to multiply any number represented


in base 2 by a power of 2 (for example 2n) by doing n left bit shifts and backfilling with 0's.
Note that this also works for multiplication of negative 2's complement (or integer) numbers.
Multiplying 111100012 (-15) by 2 is done by moving the bits left 1 space and again appending a
0, yielding 111000102 (or -30) (note that in this case 0 is used for positive or negative numbers).
Again multiply 111100012 (-15) by 8 is done using 3 bit shifts and backfilling the number again
with zeros, yielding 100010002 (-120)
By applying simple arithmetic, it is easy to see how to do multiplication by a constant 10.
Multiplication by 10 can be thought of as multiplication by (8+2), so (n*10) = ((n*8)+(n*2)).

15*10 = 15 * (8+2) = 15 *8 + 15 * 2 = (000011112 << 3) + (000011112 << 1) =


11110002 + 111102 = 1001001102 = 150
This factoring procedure applies for multiplication by any constant, as any constant can be
represented by adding powers of 2. Thus any constant multiplication can be encoded in assembly
as a series of shifts and adds. This is sometimes faster, and often easier, than doing the math
operations, and should be something every assembly language programmer should be familiar
with.
This explanation of the constant multiplication trick works in assembly, which begs the question
does it also work in a HLL? The answer is yes and no. Bit shifts and addition can be done in most
programming languages, so constant multiplication can be implemented as bits shifts and addition.
But because it can be done does not mean it should be done. In HLL (C/C++, Java, C#, etc.) this
type of code is arcane, and difficult to read and understand. In addition, any decent compiler will
convert constant multiplication into the correct underlying bit shifts and additions when it is more
efficient to do so. And the compiler will make better decisions about when to use this method of
multiplication, and implement it more effectively and with fewer errors than if a programmer were
to do it. So unless there is some really good reason to do multiplication using bit shifts and
addition, it should be avoided in a HLL.

Chapter 1.6. 4 Integer division using bit shift operations


Since multiplication can be implemented using bit shift operations, the obvious question is
whether or not the same principal applies to division? The answer is that for some useful cases,
division using bit shift operations does work. But in general, it is full of problems.
The cases where division using bit shift operations works are when the dividend is positive, and
the divisor is a power of 2. For example, 000110012 (25) divided by 2 would be a 1-bit shift, or
000011002 (12). The answer 12.5 is truncated, as this is easily implemented by throwing away the
bit which has been shifted out. Likewise,00 0110012 (25) divided by 2 is 000000112 (3), with
truncation again occurring. Note also that in this case the bit that is shifted in is the sign bit, which
is necessary to maintain the correct sign of the number.
Bit shifting for division is useful in some algorithms such as a binary search finding parents in a
complete binary tree. But again it should be avoided unless there is a strong reason to use it in a
HLL.
29 INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING

This leaves two issues. The first is why can this method not be implemented with constants other
than the powers of 2. The reason is that division is only distributive in one direction over addition,
and in our case it is the wrong direction. Consider the equation 60/10. It is easy to show that
division over addition does not work in this case.
60/10 = 60/(8+2) ≠ 60/8 + 60/2
The second issue is why the dividend must be positive. To see why this is true, consider the
following division, -15 / 2. This result in the following:
111110012 >> 1 = 11111100 = -8
Two things about this answer. First in this case the sign bit, 1, must be shifted in to maintain the
sign of the integer.
Second in this case the lowest bit, a 1, is truncated. This means that -7.5 is truncated down to -8.
However, many programmers believe that -7.5 should truncate to -7. Whether the correct answer
is -7 or -8 is debatable, and different programming languages have implemented as either value
(for example, Java implements -15/2 = -7, but Python -15/2 as -8). This same problem occurs with
many operations on negative numbers, such a modulus. And while such debates might be fun, and
programmers should realize that these issues can occur, it is not the purpose of this book to do
more than present the problem.

Chapter 1. 7 Boolean Logical and Bitwise Operators


Chapter 1.7. 1 Boolean Operators
Boolean operators are operators which are designed to operate on a Boolean or binary data. They
take in one or more input values of 0/14 and combine those bits to create an output value which is
either 0/1. This text will only deal with the most common Boolean operators, the unary
operator NOT (or inverse), and the binary operators5 AND, OR, NAND, NOR, and XOR. These
operators are usually characterized by their truth tables, and two truth tables are given below for
these operators.

A NOT
0 1
1 0
Table 1-6: Truth table for NOT operator

4
Note that the values 0/1 are used here rather than F/T. These operators will be described through the rest of the
book using the binary values 0/1, so there is no reason to be inconsistent here.
5
The term unary operator means having one input. The term binary operator means having two inputs. Be careful
reading this sentence, as binary is used in two different contexts. The binary operator AND operates on binary data.
INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING 30

Input Output
A B AND OR NAND NOR XOR
0 0 0 0 1 1 0
0 1 0 1 1 0 1
1 0 0 1 1 0 1
1 1 1 1 0 0 0
Table 1-7: Truth table for AND, OR, NAND, NOR, and XOR

Chapter 1.7. 2 Logical and Bitwise Boolean Operators


There are two kinds of Boolean operators implemented in many programming languages. They
are logical operators and bitwise operators. Logical operators perform Boolean operations to
obtain a single value at the end. For example, in Java a programmer might write:
if ((x != 0) && (y / x > 4))

The purpose of this statement is to decide whether or not to enter the statement or code block
associated with the if test. What is desired is a single answer, or a single bit, which is either true
(1) or false (0). This has two consequences. The first is that in some programming languages (e.g.
C/C++) a variable other than a Boolean can be used in the statement, with the consequence that
0 is false, and anything but 0 is true. For example, in the statement if(x=64), the result is true.
The equal operator returns a non-zero value, 64, which is true. This has been the cause of many
bugs in C/C++, and most modern compilers at least complain about this. This will also be the
result of some expressions in assembler, and there will be no compiler to complain about it. So
be careful.
The second consequence of the logical Boolean operator is that once a part of it has failed, the
entire statement has to fail, and so the rest of the statement will not be executed. This is called
short circuiting, and all logical operators are thus short-circuiting operators. To see why this is
true, consider the if test about. In this if test, if x is 0, then (x != 0) is false. Since false and
anything is false, there is no need to evaluate the second part of this equation, and so the statement
(y / x > 4) is not executed. Many programmers will recognize this code, as it is a common
pattern for protecting against a zero divide.
The important take away from this is that logical operators are short circuiting operators.
On the other hand, bit-wise operators are not short circuiting. Consider the following problem.
A programmer wants to write a toLower method which will convert an upper-case letter to a
lower-case letter. In chapter 1.3 it was pointed out that the difference between an upper-case
letter and a lower-case letter is that in a lower case letter the bit 0x20 (001000002) is 1, whereas
in the upper case letter it is zero. So, to convert from upper case letter to lower case, it is only
necessary to OR the upper case letter with 0x20. In pseudo code this could be implemented as
follows:
char toLower(char c) {
return (c | 0x20)
}
31 INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING

In this case the OR operator, |, needs to operator on every bit in the variables. Therefore, the |
operator is not short circuiting, it will process every bit regardless of whether or not a previous
bit would cause the operation to fail.
It is possible to use bitwise operators in place of logical operators, but it is usually incorrect to do
so. For example, in the previous if statement, if a bitwise operator had been used no short circuiting
would have occurred and the zero divide could occur.
if ((x != 0) & (y / x > 4))

Many languages such as C/C++, Java, C#, etc, have both logical (short circuiting) and bitwise
operators. In most cases the single character operator is a bit wise operator (e.g. &, |, etc.) and
the double character operator is the logical operator (&&, ||, etc.).

To make things more confusing, in MIPS only non-short-circuiting operators are used, however
they are often called logical operators. There is no good way to reconcile this, so the user is
cautioned to read the material and programs carefully.

Chapter 1. 8 Context
The final bit of information to take from this chapter is that data in a computer is a series of "1"
or "0" bits. In computer memory two bytes containing “01000001” could exists. The question is
what does this byte mean? Is the byte an integer number corresponding to decimal 65? Is this an
ASCII character, representing the letter "A". Is it a floating-point number, or maybe an address?
The answer is you have no idea!
To understand data there has to be a context. HLL alway provide the context with the data (for
example, the type, as in int a;), so the programmer does not have to worry about it. However, in
assembly the only context is the one the programmer maintains, and it is external to the program.
Is it possible to convert an integer number from upper case to lower case? Or to add two
operations? The answer is yes, anything is possible in assembly, but that does not mean it makes
sense to do it.
In assembly language it is important for the programmer to always be aware of what a series of
bits in memory represents, or the context of the data. Remember that data without a context is
never meaningful.

Chapter 1. 9 Summary
In this chapter the concept of binary was introduced, as well as ways to represent binary data
such as binary whole numbers, integers, and ASCII. Arithmetic and logical operations were
defined for binary data. Finally, the chapter introduced the concept of a context, where the
context defines the meaning of any binary data.

Chapter 1. 10 Exercises
1) What are the following numbers in binary and hexadecimal?
a. 1310
b. 1510
INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING 32

c. 2510
d. 15710
e. 32510
f. 109610

2) What are the following numbers in decimal?


a. 100111002
b. 9C16
c. 1F16
d. 0C16
e. 109A16

3) Give the value of the following numbers (IE. 232 = 4G)


a. 216
b. 224
c. 229
d. 234
e. 231

4) Give the 2’s complement form for each of the following numbers:
a. 13
b. -13
c. 156
d. -209

5) Do the following calculations using 2’s complement arithmetic. Show whether there is an
overflow condition or not. CHECK YOUR ANSWERS!
a. 13 + 8 with 5 bits precision
b. 13 + 8 with 6 bits precision
c. 13 – 8 with 5 bits precision
d. 13 – 8 with 6 bits precision
e. -13 – 8 with 5 bits precision
f. -13 – 8 with 6 bits precision
g. 105 – 57 with 8 bits precision

6) Do the following multiplication operations using binary shift operations. Check your
answers.
a. 5 * 4
b. 13 * 12
c. 7 * 10
d. 15 * 5

7) What is the hex representation of the following numbers (note that they are strings):
a. “52”
b. “-127”
33 INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING

8) Perform the following multiplication and division operations using only bit shifts.
a. 12 * 4
b. 8 * 16
c. 12 * 10
d. 7 * 15
e. 12 / 8
f. 64 / 16

9) Explain the difference between a short circuiting and non-short-circuiting logical expression.
Why do you think these both exist?

10) In your own words, explain why the context of data found in a computer is important. What
provides the context for data?

11) Convert the following ASCII characters from upper case to lower case. Do not refer to the
ASCII table.
a. 0x41 (character A)
b. 0x47 (character G)
c. 0x57 (character W)

12) Convert the following ASCII characters from lower case to upper case. Do not refer to the
ASCII table.
a. 0x 62 (character b)
b. 0x69 (character i)
c. 0x6e (character n)

13) Write the functions toUpper and toLower in the HLL of your choice (C/C++, Java, C#, etc.)
The toUpper function converts the input parameter string so that all characters are uppercase.
The toLower function converts the input parameter string so that all characters are lowercase.
Note that the input parameter string to both functions can contain both upper- and lower-case
letters, so you should not attempt to do this using addition.

14) Implement a program in the HLL of your choice that converts an ASCII string of characters
to an integer value. You must use the follow pseducode algorithm:

read numberString
outputNumber = 0
while (moreCharacters) {
c = getNextCharacter
num = c - '0';
outputNumber = outputNumber * 10 + num;
}
print outputNumber;

15) Write a program in the HLL of your choice to take a string representing a binary number, and
write out the number in hex.
INTRODUCTION TO MIPS ASSEMBLY LANGUAGE PROGRAMMING 34

16) Write a program in the HLL of your choice to take an integer and write its value out in hex.
You cannot use string formatting characters.

17) Is bit shift by 1 bit the same as division by 2 for negative integer numbers? Why or why not?

18) Can multiplication of two variables (not constants) be implemented using the bit shift
operations covered in this chapter? Would you consider using the bit shift operations
implementation of multiplication and divide for two variables, or would you always use the
mul or div operators in MIPS assembly? Defend your choice.

19) Should you use bit shift operations to implement multiplication or division by a constant in a
HLL? What about assembly makes it more appropriate to use these operations?

20) What does the Unix strings command do? How does the command attempt to provide a
context to data? How might you use it?

Type your text


OXJORD

i l \ JL l i W x i L_ C O v/ I

COMPUTER
HARDWARE FOURTH EDITION

A L an CL ement s

online INCLUDES^ |
resource FREE "M
centre CD-ROM W
The instruction set architecture
CHAPTER MAP

2 Logic elements and 7 Structure of the CPU


5 The instruction set 6 Assembly language
i Boolean algebra Having described what a
architecture programming
The basic building blocks, gates, . computer does, thenextstep is
Having introduced the basic
f: from which we construct the !'i I'VS chapu-r v.c iritiodt.;* thi!
operations that a computer can i to show howM operates. Here we
I computer. computer's instrut t:on id carry, the next step is to show examine the internal organization
iJ.-c.,:/tcrtu.n'(ISA'n,vhvli how they are used to construct of a computer and demonstrate
eestiibestlielow ipvui entire programs.We look at how how it reads instructions from
programmer's vis1/.- of :he the 6BK processor uses machine-
memory, decodes them, and
3 Sequential logic compute.- rne ISA deiini-i tiir-
tevel instructions to implement
executes them.
'.. The building blocks, flip-flops, type- of operation* d computor some simple algorithms.
••" used to construct devices that cernos
• ,-iu! V,'e E'I- .-itere.'ir'd m
"store data and counters. thrre .-ispeits or the ibA-lhc
nature of the ns::iic::ons *.*M 8 Other processors
leMnirceiiisftlby the We have used the 68K to
introduce the CPU and assembly
4 Computer arithmetic •ns'.rutt'ons (•easier;, and
memory), .mcl the ways in ivnicri language programming. Here we
The representation of numbers in.
provide a brief overview of two
a computer and the arithmetic t"ie instructions access dald
(adfrcssinf -i-oae.j.Trie 68K other processors: a jimpie 8-bit
Used by digital computers.
mi:ropiowssor is used to microcontroller and a 32-bit RISC
ilijaiMtr iii«r operi-.t'ijn t:! a --*3l processor.

INTRODUCTION
There are two ways of introducing the processor. One is to explain how a computer works at the
level of its internal information flow by describing the way in which information is transmitted
between registers and internal units and showing how an instruction is decoded and interpreted
(i.e. executed).The other approach is to introduce the native language, or machine code, of a
computer and show what computer instructions can do. In practice no-one writes programs in
machine code; instead they use assembly language which is a human-readable representation of
machine code (see the box 'The assembler').
Both approaches to the description of a computer are valid. Beginning with how a computer
works by examining its internal operation is intuitive. Once you understand how information flows
from place to place through adders and subtractors, you can see how instructions
are constructed and then you can examine how sequences of instructions implement
programs.
Unfortunately, beginning with the hardware and looking at very primitive operations hides the
big picture. You don't immediately see where you are going or understand why we need the
primitive operations in the first place. This bottom-up approach is rather like studying cellular
biochemistry as the first step in a course on sociology. Knowing how a brain cell works doesn't tell
you anything about human personality.
204 Chapter 5 The instruction set architecture

Beginning a course with the computer's instruction set gives you a better idea of what a
computer does in terms of its capabilities. Once you know what a computer does, you can look
inside it and explain how it implements its machine code operations.
In the previous edition of Principles of Computer Hardware I began with the internal
organization of a computer and explained the steps involved in the execution of an instruction.
Later we looked at the nature of instructions. In this edition I've reversed the order and we begin
with the instruction set and leave the internal organization of the computer until later. This
sequence enables students to take lab classes early in the semester and build up practical
experience by writing assembly language programs.
We begin this chapter by introducing the notion of computer architecture, the instruction
set, and the structure of a computer. We describe a real processor, the Motorola 68K.
This processor is a contemporary of the Intel 8086 but has a more sophisticated
architecture and its instruction set is easier for students to understand. This processor
has evolved like the corresponding Intel family and its variants are now called the
ColdFire family.

THE ASSEMBLER
An assembly language program starts off as a text file written by a programmer (or created by
a compiler). An assembler takes the text file together with any library functions required by
the program and generates the binary code that the target executes.
The addresses of code and data generated by the assembler are not absolute (i.e. actual), but
refer to the tocations with respect to the start of the program. Another program called a linker
takes one or more code modules generated by the assembler, puts them together, and creates
the actual addresses of data in memory. The output of the linker is the binary that can be exe-
cuted by the actual computer.This mechanism allows you to write a program in small chunks
and to put them together without having to worry about addresses in the different chunks.

Assembly language
program Assembler Linker

Source code
The linker takes one
MOVE.B #4,DO The assembler or more separately
MOVE.B #9,D1 translates assembly assembled modules
language into binary • Binary
ADD.B D0.D1 and puts them together
MULD #5,D1 code (machine code). to generate the final
binary code.
i

Library
The library contains
commonly used
functions such as
I/O routines.

the 1960s and IBM's 360 series mainframes. Each mainframe


5.1 What is an instruction set had the same architecture, but the performance varied from
architecture? model to model. By adopting a common architecture for all
members of the 360 series, users were able to upgrade a
An instruction set architecture (ISA) is an abstract model of a model and still use the same software.
computer that describes what it does, rather than how it does An object can be viewed in more than one way. Consider
it. You could say that a computer's architecture is its func- the airline pilot. Passengers see the pilot as an agent responsi-
tional definition. The notion of an architecture dates back to ble for transferring them from one airport to another. The
5.1 What is an instruction set architecture? 205

pilot's crew sees them as a colleague with whom they relate at Figure 5.1 illustrates how a computer can be viewed in differ-
the personal level. The pilot's doctor sees a complex biologi- ent ways. The outer level is the applications layer that the end
cal mechanism. It's exactly the same with computers—you user sees. This level provides a virtual spreadsheet or any
can view them in different ways. other user-application because, to all intents and purposes,
Suppose you run a spreadsheet on a computer. As far as the machine looks like a spreadsheet machine that does noth-
you're concerned, the machine is a spreadsheet machine that ing else other than implement spreadsheets.
behaves exactly as if it were an electronic spreadsheet doing A spreadsheet, a word processor, or a game is invariably
nothing other than spreadsheet calculations. You could con- implemented by expressing its behavior in a high-level lan-
struct an electronic device to directly handle spreadsheets, but guage such as C or Java. You can view a computer as a
no one does. Instead they construct a computer and run a machine that directly executes the instructions of a high-level
program to simulate a spreadsheet. language. In Fig. 5.1 the layer below the application level is
the high-level language layer.
ARCHITECTURE AND ORGANIZATION
It's difficult to construct a computer that executes a high-
level language like C. Computers execute machine code, a
Architecture describes the functionality of a system, whereas
primitive language consisting of simple operations such as
organization describes how it achieves that functionality.
addition and subtraction, Boolean operations, and data
Consider the automobile as a good example of the distinction
movement. The statements and constructs of a high-level
between architecture and organization. The architecture of an
automobile covers its steering, acceleration, and braking. An language are translated into sequences of machine code
automobile's gearbox is part of its organization rather than its instructions by a compiler. The machine code layer in Fig. 5.1
architecture. Why? Because the gearbox is a device that is responsible for executing machine code; it's this layer that
facilitates the operation of an automobile—it is there only defines the computer's architecture.
because we can't create engines that drive wheels directly. Figure 5.1 shows two layers between the machine level and
high-level language levels. The assembly language level sits on

Application
Word processor
High-level Database
language Came

Operating
system
-""""Assembly """-- c
Language — Java
LISP
Machine level

Windows
• "" Unix
/^icrcprcgram

' Digi:al
Uoglc

Hardware/software
nterface

Figure 5.1 Machine levels and virtual architectures.


206 Chapter 5 The instruction set architecture

top of the machine level and represents the human-readable the individual logic elements are hardwired to each other by
form of the machine code; for example, the binary fixed connections. You can't program or modify the behavior
string 00000010100000010001000000000011 might be the of components at this level. This statement isn't strictly true.
machine code instruction represented in assembly language Programmable logic elements whose functionality can be
as MOVE D2, Dl (move the number in register D2 to the modified do exist; for example, it is possible to reconfigure
register Dl). 1 internal connections using the same technology found in
To say that assembly language is just a human-readable flash memory. In the future we may incorporate such comp-
version of machine code is a little simplistic. An assembly lan- onents in processors to enable manufacturers to update a
guage contains facilities that make it easier for a human to processor's instruction set or to fix hardware bugs.
write a program. Moreover, an assembly language allows you You could, in fact, go even deeper into the hierarchy of
to determine where data and code is loaded into memory. We Fig. 5.1 because there is a physical layer below the digital logic
will not use sophisticated assembly language mechanisms layer. This physical layer is concerned with the individual
and it is reasonably true to say that assembly language transistors and components of the computer that are used to
instructions are human-readable versions of the strings of Is fabricate gates, registers, and buses. Below the physical layer
and 0s that represent the machine-code binary instructions. exists the individual atoms of the transistors themselves.
The conventions we will adopt in the structure and layout of We're not interested in the physical layer and the atomic
assembly language programs are, normally, those of the layers, because that's the province of the semiconductor
Motorola assembler. engineer and physicist. In this chapter we are concerned with
In Fig. 5.1 there is an additional layer between the assembly the machine-level and microprogram layers.
language layer and the high-level language layer called the operat-
ing system level. Strictly speaking, this layer isn't like the other lay-
ers. The operating system runs on top of the machine code and
assembly language layers and provides facilities required by 5.2 Introduction t o the CPU
higher-level layers (e.g. memory management and the control of
peripherals such as the display and disk drives). Before we look at what a CPU does or how it works, it is
Below the machine-level layer is the microprogram layer. A important to understand the relationship between the CPU,
heavy line separates the machine level and microprogram the memory, and the program. Let's take a simple program to
layers because you can access all the layers above this line. The calculate the area of a circle and see how the computer deals
two innermost layers (microprogram and digital logic) are with it. In what follows the computer is a hypothetical
not accessible to the programmer. machine devoid of all the complications associated with real-
The microprogram layer is concerned with the primitive ity. Throughout this section we assume that we are operating
operations that take place inside the computer during the at the machine level.
execution of a machine code operation. For example, a MOVE The area of a circle, A, can be calculated from the
D2, Dl machine-level instruction might be interpreted by formula A = irr 2 . When people evaluate the area of a circle,
executing a sequence of micro-operations inside the com- they automatically perform many of the calculations at a sub-
puter. These micro-operations transfer information between conscious level. However, when they come to write programs,
functional units such as registers and buses. The sequences of they must tell the computer exactly what it must do, step by
micro-operations that interpret each machine level instruc- step. To illustrate this point, take a look at the expression TIT2.
tion are stored in firmware within the computer. Firmware is We write r2, but we mean a number, which we have given the
the term for read-only memory containing programs or symbol r, multiplied by itself. We never confuse the symbol r
other data that controls the processor's operation. Firmware with the value that we give to r when we evaluate the expres-
cannot normally be modified, although modern systems can sion. This may seem an obvious point, but students some-
update their firmware from time to time. times have great difficulty when they encounter the concepts
Some modern computers don't have a microprogram layer. of an address and data in assembly language. Although
If an instruction set is very regular and all instructions involve people never confuse the symbol for the radius (i.e. r) and its
a simple, single-step operation, there is no need for a micro- value, say 4 cm, you must remember that an address (i.e. the
program to translate instructions into primitive operations. place where the value of r is stored) and data (i.e. the value
Where mere's a simple relationship between the binary code of r) are both binary quantities inside the computer.
of an instruction and what it does, the microprogram layer
direcdy translates a machine-level instruction into the control 1
Throughout this chapter we adopt the convention used by the 68K
signals required to implement the instruction. microprocessor diat the rightmost register in an instruction is the desti-
The innermost level of the computer is the digital logic level nation operand (i.e. where the result goes). To help you remember this,
which consists of the gates, flip-flops, and buses. At this level we will use a bold face to indicate the destination operand.
5.2 Introduction to the CPU 207

Memory

Program

getr
square r
multiply i2 by TC
output the result

Constants read A
n Processor
(CPU) j
Variables
A
r

INPUT Figure 5.2 The relationship


External
between the memory,
system <s OUTPUT
processor, and program.

Figure 5.2 illustrates the relationship between the


program, memory, and processor. The memory has been
5.2.1 The memory and registers
divided into five parts: program, constants, variables, input, We now introduce two important concepts. The first is the
and output. The program is composed of the sequence of notion of a memory that holds programs and data. The
operations to be carried out, or executed. The constants second concept is the algebraic notation we use to define
(in this case there is only one—TT) are numbers used by operations taking place within a computer.
the program but which do not change during its execution. Figure 5.3 illustrates the so-called random access memory
The variables represent numbers created and modified by the system (i.e. RAM). This memory appears as a block of
program. When the program squares r, it reads the value of sequential locations, each of which contains a data element.
the number in the memory location it has called r, squares it, Each location has a unique address that defines the location
and puts the result back in the same location. Thus the of the data; for example, in Fig. 5.3 we can say that location
original value of r is lost. If the programmer wishes to retain number 5 contains the value 7.
the original value of r, rather than by overwriting it with r2, The memory in Fig. 5.3 is interfaced to the rest of the
memory locations must be reserved for both r and r2. computer via three buses (i.e. information paths). The
Although the variables (i.e. the values held in memory address bus is a one-way path from the computer to the
locations) are often numerical quantities, there is no reason memory, which specifies the location of the memory element
why this must always be so. For example, the variables used by being accessed. The data bus is a bidirectional (i.e. two-way)
a word processor are the letters and symbols of the text being data path along which data flows into memory when it is
manipulated. Indeed, it is perfectly possible for the variable to stored and out of memory when it is retrieved. The control
be another program. That is, one program can operate on, or bus includes signals that control the operation of the
modify, another program. memory (e.g. read data or write data commands).
A program must be able to communicate with the outside
world, otherwise all its efforts are to no effect. We have labeled Registers
two memory locations in Fig. 5.2 input and output. Reading A register is a storage device that holds a word exactly like a
from the input location causes information to be taken from memory location. In principle, there's no difference between
an input device (say a keyboard) and writing to the output a location in memory and a register because they both do
location causes information to be moved from the computer the same thing. The real difference is one of accessibility.
to an output device (say a display). Treating input and output Registers are located within the CPU and can be accessed
as memory locations is not entirely fictional—we'll later faster than memory locations. Moreover, there are few regis-
discover that many computers really do perform all ters in a computer and millions of address locations, which
input/output transactions via the memory by means of a means that you need far fewer bits to specify a register than a
mechanism called memory-mapped I/O. memory location. For example, the 68K has eight data regis-
The processor may either read data from a memory loca- ters and an instruction requires 3 bits to specify which one of
tion or write data to a memory location. Of the five regions of the eight registers is to be used by an instruction. If you spec-
memory described above, three are read-only, one is write- ify a memory location, you need 32 bits to select one out of
only, and one can be read from or written to. 232 possible locations.
208 Chapter 5 The instruction set architecture

Memory system
Processor Address port
0 7
1 3
Address bus Address
Address 2 15
(location 4)
3 2C
L-^-
4-* - " ~ ~ 3 «
Data port Memory cell
5 7 containing the
6 3 value 3
Data Data bus^
7 8
8 8
9 42
Control Control bus
signals 10 12
11 19
The control bus
determines the
Figure 5.3 The random
direction of information
transfer access memory system.

Registers are not a necessary component of computers—


5.2.2 Register transfer language
we could use memory to store all variables and temporary
data. Registers exist because they are required to construct Throughout this book we adopt shorthand called register
practical computers. We could not build cheap, fast, and transfer language (RTL) to help us to explain how the CPU
effective computers without registers. operates. RTL is an algebraic notation that describes how
Registers are used as temporary storage places to hold fre- information is accessed from memories and registers and
quently used data. Much of a computer's activity is of the how it is operated on. You should appreciate that RTL is just a
form copy data from a memory location to a register, operate on notation and not a programming language.
the data in the register, send the data back to memory. This RTL uses variables like algebra or computer languages; for
sequence involves a lot of moving data from one place to example, one or more letters (or letters followed by numbers)
another place. to denote registers or storage locations.
The size of a register (its width in bits) is normally the same It's very important to distinguish between a memory loca-
size as memory locations and the size of the arithmetic and tion and its contents. RTL uses square brackets to indicate the
logical operations in the CPU. If you have a computer with contents of a memory location; for example, the expression
32-bit words, they are held in 32-bit memory locations and [6] = 3
32-bit registers and are processed by 32-bit adders, and so on.
Some registers are said to be visible and some are invisible is interpreted as the contents of memory location 6 contains the
to the programmer. In this chapter we are interested only in value 3. If we were using symbolic names, we might write
programmer-visible registers. A register is visible if it can be [Time] = HoursWorked
directly accessed by the programmer though a computer
When dealing with registers, we use their name rather than
operation. A register is invisible if it is required for internal
an address; for example,
operations but cannot be directly accessed by the program-
[D4] = PQR
mer. The 68K's visible register set consists of
A left or backward arrow (<—) indicates the transfer of data.
• eight 32-bit data registers (DO to D7)
The left-hand side of an expression denotes the destination of
• eight 32-bit address registers (pointers) (A0 to A7) the data defined by the source of the data defined on the right-
• a 16-bit status register (SR) hand side of the expression. For example, the expression
• a 32-bit program counter (PC). [MAR] <- [PC]

The address and data registers are used by the programmer indicates that the contents of the program counter (PC) are
to hold temporary data. The status register defines the transferred (i.e. copied) into the memory address register
processor's current operating mode and keeps track of things (MAR). The program counter is the register that holds the
like the carry-out when you do addition. The program location (i.e. address) of the next instruction to be executed.
counter contains the location of the next instruction to be The MAR is a register that holds the address of the next item
executed and, therefore, keeps track of where the computer is to be read from memory or written to memory. Note that the
up to in a program. contents of the PC are not modified by this operation.
5.2 Introduction to the CPU 209

The operation computer language; it is a notation used to define computer


[3] <- [5] operations.
Later in this chapter we use the 68K's processor's assembly
means copy the contents of memory location 5 to location 3.
language. The typographic conventions in an assembly
In previous editions of this book we used the notation
language differ from those of RTL. We use RTL to define the
[M (5) ] to indicate the contents of memory location 5. We
meaning of assembly language instructions. Consider the
have simplified the notation because the meaning of the following examples.
notation [ 5 ] is clear and it's easier to read than [M (5) ] .
Processor Instruction RTL definition
If we were writing a program, memory locations 3 and 5 family mnemonic
would have been given symbolic names, say, x and y, respec- 1. 68K MOVE DO, (A5) [A5] <- [DO]
tively. A symbolic name is the name given to a number by the 2. A R M ADD R1,R2,R3 [Rl] <- [R2] + [R3]
programmer—people like to deal with meaningful names 3. IA32 MOV ah, 6 [ah] <- 6
rather than, say, the actual numeric addresses of data in 3. PowerPC li r 2 5 , 10 [r25] <r- 10
memory. The operation [3] <- [5] tells us what's happening
at the micro level—at the high level this operation might be
5.2.3 Structure of the CPU
written in the rather more familiar form
x = y; Figure 5.4 provides a more detailed view of the central
processing unit and memory system. The same memory
Consider the RTL expression
system stores both the program and the data acted on or
[PC] <- [PC] + 4 created by the program. It isn't necessary to store both the
which indicates that the number in the PC is increased by 4; program and data in the same memory. However, for largely
that is, the contents of the program counter are read, 4 is economic reasons, most computers do store programs and
added, and the result is copied into die PC. data in a single memory system. Such computers are called
Suppose the computer executes an operation that stores von Neumann machines in honor of John von Neumann.
the contents of the PC in location 2000 in the memory. We A computer is a black box that moves information from
can represent this action in RTL as one point to another and processes the information as it goes
along. By information we mean the data and the instructions
[2000] [PC]
held inside the computer. Figure 5.4 shows two information-
Occasionally, we wish to refer to the individual bits of a carrying paths between the CPU and its memory. The lower
register or memory location. We will do this by means of the path (dark blue) with the single arrowhead from the memory
subscript notation (p:q) to mean bits p to q inclusive; for to the CPU indicates the route taken by the computer's pro-
example if we wish to indicate that bits 0 to 7 of a 32-bit reg- gram. The CPU reads the sequence of commands that make
ister are set to zero, we write2 up a program one by one from its memory.
[R6(0:7)] <- 0 The upper path (light blue in Fig. 5.4) with arrows at
both its ends transfers data between the CPU and memory. The
Numbers are assumed to be decimal, unless indicated oth- program being executed controls the flow of information along
erwise. Computer languages adopt conventions such as the data path. This data path is bidirectional, because data can
0xl2AC or $12AC to indicate hexadecimal values. In RTL we
will use a subscript; that is, 12AC16.
As a final example of RTL notation, consider the following Memory
RTL expressions. Input
(a) [20] = 6 Central A- -N Data
processing V-
(b) [20] <- 6 unit
(c) [20] <r- [6] (CPU)
(d) [20] <- [6] + 3 Output A- Pic-j-r;,
The first example states that memory location 20 contains
the value 6. The second example states that the number 6 is
C
copied or loaded into memory location 20. The third example
Figure 5.4 The general-purpose digital computer.
indicates that die contents of memory location 6 are copied
into memory location 20. The last example reads the contents
of location 6, adds 3 to it, and stores the result in location 20. 2
In the previous editions of this book, we used the notation
The RTL symbol '<-' is equivalent to the assignment symbol [R3 (0:7) ] to indicate bits 0 to 7 of R3. However, by using the
in high-level languages. Remember that RTL is not a subscript [ R3 , 0 . 7 , ] we make it easier to indicate a register's subsection.
210 Chapters The instruction set architecture

RISC AND CISC PROCESSORS

Processors fall into two classes: CISC (complex instruction set acceleration techniques later become known as RISCs.The
computer) and RISC (reduced instruction set computer). term RISC was coined in the early 1980s by John Hennessey
Intel's Pentium and Motorola's 68K families are CISC at Stanford University.
processors with large, irregular instruction sets. CSIC RISC processors have lots of on-chip registers and do not
processors can perform operations directly on the contents of allow you to perform operations directly on data in memory.
memory locations, whereas RISC processors perform You have to load data into a register, process it, and then store
operations only on the contents of registers. it in memory. For this reason, RISC processors are also called
The acronym RISC is misleading. Before the advent of RISC load/store processors.
technology, processors had complex and elaborate instruction The goal of RISC processor design was to execute an aver-
sets with instruction lengths varying from 16 bits to 80 bits. age of one instruction per clock cycle by overlapping the exe-
These processors are retrospectively called CISCs. RISC instruc- cution of consecutive instructions (i.e. starting executing the
tions are the same length with few variations in their formats. next instruction before the current instruction has finished). In
Until the mid-1970s the notation of a RISC processor didn't order to do this, it is necessary that there is a simple relation-
exist. IBM investigated ways of accelerating computer perfor- ship between the bit pattern of an instruction and what the
mance in the 1970s and the computers incorporating IBM's instruction does.

flow in two directions. During a write cycle data generated by the machine is harder to learn, but it does illustrate the real-world
program flows from the CPU to the memory where it is stored constraints faced by its designer.
for later use. During a read cycle the CPU requests the retrieval There's no perfect solution to this dilemma. We've chosen
of a data item that is transferred from the memory to the CPU. a real machine, the 68K, to introduce an assembly language
Suppose the instruction ADD x, Y, z corresponding to the and machine-level instructions. The 68K is a classic CISC
operation X = Y + Z is stored in memory.3 The CPU must processor and is easer to understand than the Pentium family
first fetch this instruction from memory and bring it to the because the 68K has a more regular instruction set. Another
CPU. Once the CPU has analyzed or decoded the instruction, reason for using the 68K processor to illustrate the ISA is its
the CPU has to get the values of X and Y from memory. The interesting architectural features.
actual values of X and Y are read from the memory and sent to The architecture of a processor is defined by its register set,
the CPU. The CPU adds these values and sends the result, Z, its instruction set, and its addressing modes (the way in which
back to memory for storage. Remember that x, Y, and z are the location of data in memory is specified). Figure 5.5
symbolic names for the locations of data in memory. describes the 68K's register set. There are eight data registers
Few computers are constructed with two independent used to hold temporary variables, eight address registers used
information paths between the CPU and its memory as to hold pointers to data, a status register, and a program
Fig. 5.4 suggests. Most computers have only one path along counter, which determines the next instruction to be executed.
which information flows between the CPU and its memory— Data registers are 32 bits wide and but can be treated as if
data and instructions have to take turns flowing along this they were 8 or 16 bits wide. Address registers always hold 32-
path. Two paths are shown in Fig. 5.4 simply to emphasize bit values and are always treated as 32-bit registers that hold
that there are two types of information stored in the memory two's complement values. However, you can perform an
(i.e. the instructions that make up a program and the data operation on the low-order 16 bits of an address register and
used by the program). Indeed, forcing data and instructions the result will be sign-extended to 32 bits automatically.
to share the same path sometimes creates congestion on
the data bus between the CPU and memory that slows the
computer down. This effect is called the von Neumann
5.3.1 The instruction
bottleneck. We now look at the instructions executed by the 68K proces-
sor. There has been remarkably little progress in instruction
set design over the last few decades and computers do today
5.3 The 68K family almost exactly what they did in the early days.4 Much of the

Anyone introducing computer architecture and the ISA has to


3
make an important choice: should the target architecture used Strictly speaking, we should write this operation in RTL as [X] <—
[ Y] + [Z] to demonstrate that X, Y, and Z refer to memory locations.
to illustrate the course be a real machine or a hypothetical 4
An exception to this is multimedia technology. Processors such as
teaching machine? A hypothetical machine reduces the stu- Intel's Pentium family introduced a special instruction to handle the type
dent's learning curve because you can simplify it. A real of data used in audio and video processing (e.g. the MMX instruction set).
5.3 The 68K family 211

32 bits
16 bits
Suits
« k

DO
D1
The eight data registers D2
hold scratchpad
information and are used D3
by data processing D4
instructions. You can treat
data registers as 8-bit, DS
16-bit, or 32-bit entities. D6
D7

AO
The eight address registers
hold 32-bit address or pointers. A1
Address registers take part A2
only in 32-bit operations and
are used only in accessing A3
data. A4
A5
Note that address register
A7 is the system stack A6
pointer because it points to A7 SP
the top of the stack.

The program counter PC


contains the address of
the next instruction to
be executed. CCR SR
The status register contains information about
the state (operating mode) of the computer. Figure 5.5 The 68K register set.

progress over the last six decades has been in computer tech- R may be memory locations or registers. The two-address
nology, organization, and implementation rather than in instruction is in blue because that is the format used by the 68K.
computer architecture. Let's begin with three operands because it's intuitively easy
Computer instructions are executed sequentially, one by to understand. A three-address computer instruction can be
one in turn, unless a special instruction deliberately changes written
the flow of control or unless an event called an exception operation soureel,source2,destination
(interrupt) takes place. where o p e r a t i o n defines the nature of the instruction,
The structure of instructions varies from machine to s o u r c e l is the location of the first operand, source2 is the
machine. The format of an instruction running on a Pentium is
location of the second operand, and d e s t i n a t i o n is the
different to the format of an instruction running on a 68K
location of the result. The instruction ADD p, Q, R adds P and
(even though both instructions might do the same thing).
Q to get R (remember that we really means that the instruc-
Instructions are classified by type (what they do) and by the
tion adds the contents of location P to the contents of loca-
number of operands they take. The three basic instruction types
tion Q and puts the sum in location R). Having reminded you
are data movement which copies data from one location to
that when we mention a variable we mean the contents of the
another, data processing, which operates on data, and flow con-
memory location or register specified by that variable, we will
trol, which modifies the order in which instructions are exe-
not emphasize it again.
cuted. Instruction formats can take zero, one, two, or three
Modern microprocessors don't implement three-address
operands. Consider the following examples of instructions with
instructions exactly like this. It's not the fault of the instruc-
zero to three operands. In these examples operands P, Q, and
tion designer, but it's a limitation imposed by the practicali-
ties of computer technology. Suppose that a computer has a
Instruction Effect 32-bit address that allows a total of 232 bytes of memory to be
Operands
Three ADD P Q,R Add P to Q and put the result in R accessed. The three address fields, P, Q, and R would each be
Two ADD P, Q Add P to Q and put the result in Q
32 bits, requiring 3 X 32 = 96 bits to specify operands.
Assuming a 16-bit operation code (allowing up to 216 = 65 536
One ADD P Add P to an accumulator
instructions), the total instruction size would be
Zero ADD Add the top two items on the stack
212 Chapter 5 The instruction set architecture

112 bits
16 bits 32 bits 32 bits 32 bits
*.*
Destination Source 1 Source 2 The op-code and control
Op-code bits together define the
address address address
instruction. The op-code
selects the class of
(a) Format of a hypothetical instruction with three address fields instruction and the
control bits select
32 bits
options that specify how
17 bits 5 bits 5 bits 5 bits the instruction operates.
•-< *~*

Destination Source 1 Source 2


Op-code Control bits register register
register

(b) Format of a hypothetical instruction with a register-to-register architecture

Figure 5.6 Possible three-address instruction formats.

Memory

ADD R1,R2,R3 The instruction A D D R l , R 2 , R3 in


memory is read by the computer and
interpreted.The computer reads
registers R2 and R3 to obtain the two
Registers
source operands, sends these operands
RO [ to the adder in the ALU, and then
writes the sum from the adder to
register R1.
R1 I Wdderi

R2 I

R3

R4 [

Figure 5.7 Implementing a three-address instruction.

96 + 16 = 112 bits or 14 bytes. Figure 5.6(a) illustrates a the remaining 32 — 15 = 17 bits to specify the instruction, as
hypothetical three-address instruction. Fig. 5.6(b) demonstrates. Figure 5.7 illustrates the operation
Computer technology developed when memory was very of an instruction with three register addresses.
expensive indeed. Implementing a 14-byte instruction was We'll use the ADD instruction to add together four values
not cost effective in the 1970s. Even if memory had been in registers R2, R3, R4, and R5. In the following fragment of
cheap, it would have been too expensive to implement 112- code, die semicolon indicates the start of a comment field,
bit-wide data buses to move instructions from point to point which is not part of the executable code. This code is typical
in the computer. Finally, main memory is intrinsically slower of RISC processors like the ARM.
than on-chip registers.
The modern RISC processor allows you to specify three ADD R1,R2,R3 ;R1 = R2 + R3
addresses in an instruction by providing three 5-bit operand ADD Rl, Rl, R4 ;R1 = Rl + R4
address fields. This restriction lets you select from one of only ADD R1,R1,R5 ;R1 = Rl + R5
32 different operands that are located in registers within the = R2 + R3 + R4 + R5
CPU itself.5 By using on-chip registers to hold operands, the
time taken to access data is minimized because no other stor- 5
I will use RISC very loosely to indicate the class of computers that
age mechanism can be accessed as rapidly as a register. An have a register-to-register architecture such as the ARM, MIPS,
instruction with three 32-bit operands requires 3 X 5 bits to PowerPC, and SPARC. The Motorola 68K and the Intel Pentium are not
specify the operands, which allows a 32-bit instruction to use members of this group.
5.3 The 68K family 213

REGISTER-TO-REGISTER ARCHITECTURES

Computers act on data in registers or memory locations. Many that one of the source operands is destroyed by the
data processing operations operate on two operands; for instruction.
example, X + Y or X - Y or XY or Z©Y. These operations are A typical two-address instruction is ADD DO, P. This adds
said to be dyadic because they require two operands. The the contents of memory location P to the contents of register
result of such a dyadic operation generates a third operand, DO and deposits the result in location P. The original contents
called the destination operand; for example, Z = A + B. of P are destroyed.
First-generation microprocessors of the 1970s and 1980s Register-to-register architectures permit operations only on
allowed one source operand to be in memory and one the contents of on-chip registers such as ADD R l , R2, R3.The
source operand to be in a register in the CPU. A separate desti- source or destination of an operand is never a memory loca-
nation address was not permitted, forcing you to use one of tion. Consequently, registers must first be loaded from mem-
the source operands as a destination. This restriction means ory and the results of an operation transferred to memory.

Two-address machines 8-bit code is verbose because you have to load data into the
accumulator, process it, and then store it to avoid it being
A CISC machine like the 68K has a two-address instruction
overwritten by the next data processing instruction.
format. Clearly, you can't execute P = Q + R with two
operands. You can execute Q <— P + Q. One operand appears One-address machines are still widely used in embedded
twice, first as a source and then as a destination. The opera- controllers in low-cost, low-performance systems such as
tionADD P, Q performs the operation [Q] <— [P] + [QJ.The toys. We look at an 8-bit processor in Chapter 9.
price of a two-operand instruction format is the destruction,
Zero-address machines
by overwriting, of one of the source operands.
A zero-address machine doesn't specify the location of
Most computer instructions can't directly access two
an operand because the operand's location is fixed. A
memory locations. Typically, the operands are either two reg-
zero-address machine uses a stack, which is a data structure in
isters or one register and a memory location; for example, the
the form of a queue where all items are added and removed from
68K ADD instruction can be written
the same end. An ADD instruction would pop the top two items
Instruction RTL definition Mode off the stack, add them together, and push the result on the stack.
Although stack machines have been implemented to execute
ADD D 0 , D 1 [ D l ] < - [ D l ] + [DO] Register to register languages like FORTH, processors with stack-based architec-
ADD P , D 2 [ D 2 ] < - [ D 2 ] + [P] Memory to register tures have been largely confined to the research lab. There is one
ADD D 7 , P Register to memory
exception. The language JAVA is portable because it is complied
[P] < - [ P ] +[D7]
into bytecode, which runs on a stack machine, which is simu-
lated on the real target machine. We will return to the stack later.
The 68K has seven general-purpose registers, DO to D7; there
are no restrictions on the way in which you use these 68K instruction format
registers; that is, if you can use Di you can also use Dj for any
We will look at 68K instruction in detail when we've covered
iorjfromO to 7.
more of the basics. The 68K has a two-address instruction
One-address machines format. An operand may be a register or a memory location.
The following are valid 68K instructions.
A one-address machine specifies one operand in the instruction.
The second operand is a fixed register called an accumulator,
Instruction RTL definition
which doesn't have to be specified. For example, the operation
ADD D4,D1 [ D l ] <- [ D l ] + [ D 4 ]
one-address instruction ADD p means [A] <- [A] + [ P ] .
SUB P,D6 [D6] < — [D6] - [P]
The notation [A] indicates the contents of the accumulator.
AND D7,P [P] <- [ P ] A [ D 7 ]
A simple operation R = P + Q can be implemented by the
following fragment of 8-bit code (from a 6800 processor). MOVE D 3 , D 1 [ D l ] <- [ D 3 ] Register to register

LDA P ;load accumulator with P MOVE X,D1 [Dl] 4- [X] Memory to register
ADD Q ;add Q to accumulator MOVE D2,Y [Y] <- [ D 2 ] Register to memory
STA R ;store accumulator in R MOVE X,Z [Z] <—[X] The only memory to
memory operation

Eight-bit machines of the Intel 8080 and Motorola 6800 CLR DO [DO] <~ 0 Only one operand
required for the clear
eras have one-address architectures. As you can imagine, instruction
214 Chapter 5 The instruction set architecture

Consider the 68K's ADD instruction ADD $00345678, Suppose a processor supports operations that act on a
D2. This instruction performs the operation [D2] <- subsection of a register. This raises the interesting ques-
[D2] + [345678,6]. The two source operands provide the tion, 'What happens to the bits that do not take part in
addresses: one address is a memory location and the other a the operation?' Figure 5.8 demonstrates how we can handle
data register. This instruction format is sometimes called operations shorter than 32 bits. Assume that a register is
'one-and-a-half address' because you can specify only a hand- partitioned as Fig. 5.8(a) demonstrates. In this example, we
ful of registers. are going to operate on data in the least-significant byte.
CISC processors use variable-length instructions. The We can do three things, as Fig. 5.10(b) and (c) demon-
minimum 68K instruction size is 16 bits and instructions can strates. In (b) the bits not acted on remain unchanged—this
be constructed by chaining together successive 16-bit values in is the option implemented by the 68K when it operates on
memory. For example, die 68K is one of the few processors to data registers. In (c) the bits that do not take part in the oper-
provide a memory-to-memory MOVE instruction that supports ation are cleared to zero. In (d) the bits that do not take part
absolute 32-bit addressing. You can write MOVE $12345678, in the operation are set to the value of the most-significant
$ABCDDCBA, which takes 10 consecutive bytes in memory and bit (the sign bit) of the bits being operated on. This option
moves the contents of one memory location to another. preserves the sign of two's complement values. Most proces-
sors implement options (c) or (d).
Subword operations RISC processors like the ARM do not allow general data
First-generation microprocessors had 8-bit data wordlengths processing operations on fever than 32 bits. However, they do
and operations acted on 8-bit values to produce 8-bit results. support 8-bit and 16-bit load instructions with a zero or sign
When 16-bit processors appeared, operations were applied to extension.
16-bit values to create 16-bit results. However, the byte did not The 68K calls 32-bit values longwords, 16-bit values words,
go away because some types of data such as ASCII-encoded and 8-bit values bytes. Motorola's terminology is not univer-
characters map naturally on to 8-bit data elements. sal. Others use the term word to mean 32 bits and halfword to
If you wish to access bytes in a 16- or 32-bit processor, you means 16 bits. The 68K is an unusual processor because it
need special instructions. The Motorola 68K family deals with allows variable size operations on most of its data processing
8-bit, 16-bit, and 32-bit data by permitting most data process- instructions. By appending . B after an instruction, you per-
ing instructions to act on an 8-bit or a 16-bit slice of a register form an operation on a byte. Appending .w performs the
as well as the full 32 bits. RISC processors do not (generally) operation on a 16-bit word and appending . L performs the
support 8- or 16-bit operations on 32-bit registers, but they do operation on a 32-bit longword. Omitting a size suffix selects
support 8-bit and 16-bit memory accesses. a 16-bit default. Consider the following.

Unused bits Data to be modified


-•< 1

(a) This represents the data before


the operation. An operation takes
place on a slice of the register.

fb) The simplest arrangement


No change (implemented by the 68K) is to
leave bits not taking part in the
operation unchanged.

(c) Some processors perform an


0 0 0 0 0 operation on a subsection of a
register and clear all bits not taking
part in the operation to zero.

(d) If the data in a register is


a signed integer, it is necessary
s s sss s to expand the number by sign,
extending it to 32 bits after the
operation. Figure 5.8 Extending data.
5.3 The 68K family 215

Instruction RTL definition


ADD.B D0,D1 [Dl(0:,,] <-[Dl(0:7)] + [D4(0:7)]
ADD.W D0,D1 [ D l , 0 : l b l ] <- [ D l ( 0 : 1 5 l ] + [D4i0:15)]
ADD.L D0,D1 [Dl ( o:3i|] <- [ D l ( 0 : 3 1 ) ] + [D4 ( 0 : 3i,]
ADD D0,D1 [Dl(o : i5)] <- [Dl(0:i5)] + [ D 4 ( 0 : 1 5 ) ] Same a s ADD.W D0,D1

5.3.2 Overview of addressing modes called immediate because the constant is part of the instruc-
tion and is immediately available to the computer. The
A key concept in computing in b o t h high- and low-level lan- addressing m o d e is also called immediate because the
guages is the addressing mode. Computers perform opera- operand is immediately available from the instruction and
tions o n data and you have to specify where the data comes you don't have to fetch it from m e m o r y or a register. W h e n
from. T h e various ways of specifying the source or destina- you specify the absolute address of a source operand, the
tion of an operand are called addressing modes. computer has to get the address from the instruction and
We can't discuss instructions, the ISA, or low-level pro- then read the data at that location.
g r a m m i n g until we have introduced three fundamental Indirect addressing specifies a pointer to the actual
concepts in addressing: operand, which is invariably in a register. For example, the
instruction, MOVE (AO) , D l first reads die contents of regis-
• Absolute addressing (the operand specifies the location
ter AO to obtain a pointer that gives you the address of
of the data)
the operand. Then it reads the m e m o r y location specified by
• Immediate addressing (the operand provides the the pointer in AO to get the actual data. This addressing m o d e
operand itself) requires three m e m o r y accesses; the first is to read the
• Indirect addressing (the operand provides a pointer instruction to identify the register containing the pointer, and
to the location of the data). the second is to read the contents of the register to get the
pointer, the third is to get the desired operand at the location
In absolute addressingyou specify an operand by providing specified by the pointer.
its location in m e m o r y or in a register. For example, ADD You can easily see why this addressing m o d e is called indi-
P, D l uses absolute addressing because die location of the rect because the address register specifies the operand indi-
operand P is specified as a m e m o r y location. Another example rectiy by telling you where it is, rather than what it is.
of absolute addressing is the instruction CLR 1234, which Motorola calls this m o d e of address register indirect address-
means set the contents of m e m o r y location 1234 to zero. ing, because the pointer to the actual operand is in an address
When you specify a data register as an operand, that is also register. Figure 5.9 illustrates the effect of executing the oper-
an example of absolute addressing, although some call it reg- ation MOVE (AO) ,D0.
ister direct addressing. In Fig. 5.9 address register AO points to a m e m o r y location;
In immediate addressing the operand is an actual value that is, the value it contains is the address of an operand in
rather than a reference to a m e m o r y location. The 68K memory. In this case AO contains 1234 and is, therefore,
assembler indicates immediate addressing by prefixing the pointing at m e m o r y location 1234. W h e n the instruction
operand with the '#' symbol; for example, ADD # 4, DO m e a n s MOVE (AO) ,D0 is executed, the contents of t h e m e m o r y
add the value 4 to the contents of register DO and p u t the location pointed at by AO (i.e. location 1234) are copied
result in register DO. Immediate addressing lets you specify a into data register DO. In this example, DO will be loaded
constant, rather than a variable. This addressing m o d e is with 3254.

DATA AND ADDRESS REGISTERS

The 68K has eight data registers, DO to D7. It also has eight part in operations only of relevance to the processing of
address registers, AO to A7. Data and address registers are addresses.
similar. Both types of registers are 32 bits wide. The principal All data registers are equal in the sense that you can use
difference between these registers lies in their function. A data any one in any way. This is not true of address registers. You
register holds any data (including addresses). An address register can use AO to A6 in any way you want but A7 is special. A7 has
is used only to hold the address of an operand in memory. a system function called the stack pointer. Address register A7
All data processing operations can be applied to any data points to the top of the system stack (the place where subrou-
register, but not to all address registers. Address registers take tine return addresses are stored).
216 Chapters The instruction set architecture

Executing a MOVE (AO) ,DO instruction The first three instructions set u p the initial
Memory values. We load AO with t h e address of t h e
AO
n u m b e r s . T h e location has the symbolic n a m e
1234 1232
'Table'. T h e # symbol precedes 'Table' because
Pointer
• 1234 3254 Do AO is being loaded with t h e address table a n d
not the contents of that address. Data register DO
Address register AO is a p o i n t e r . " "
It contains the value 1234 and,
is used to hold the sum of the numbers and is
therefore, points to address location cleared prior to its first use. Finally, we put the
1234. If you use AO to access memory, The effect of MOVE ( AO ), DO number 20 into Dl to count the elements as we
you will access location 1234. is [DO] « - [[AO]]
add them.
Figure 5.9 Address register indirect addressing. The body of the code is in blue. The first
instruction fetches the byte pointed at by AO
and adds it to the running total in DO and the second instruc-
tion points to the next byte element in the list. Note that when
Why do we implement this addressing mode? Consider the we increment the pointer we use a longword operation
following two operations. because all pointers are 32 bits.
MOVE (AO),D0 ; copy t h e i t e m p o i n t e d a t b y AO i n t o DO The last part of the program decrements the element count
ADD.L #2,A0 ; i n c r e m e n t AO t o p o i n t t o t h e n e x t i t e m by one and then branches back to 'Next' if we haven't reached
T h e first operation loads DO with the 16-bit element pointed zero. We look at the branching operations in more detail later.
at by address register AO. T h e second instruction increments The three addressing modes form a natural progression.
AO by 2 to point t o the next element. T h e increment is 2 Consider their definitions in RTL.
because the elements are 2 bytes (i.e. 16 bits) wide a n d
successive elements are 2 bytes apart in memory. Addressing mode Assembly RTL Memory
Address register indirect addressing allows you to step form accesses
t h o u g h an array o r table of values accessing consecutive ele- Immediate addressing MOVE # 4 , D 1 [Dl] < - 4 l
Absolute addressing MOVE P , D 1 [Dl] <- [ P ] 2
ments. Suppose we have a table of 20 consecutive bytes that
Indirect addressing MOVE ( A l ) , D 1 [Dl] <- [ [ A l ] ] 3
we have to add together. We can write

MOVE.L • T a b l e , A O ;A0 points to the table (AO has the address of Table)
CLR.B DO ;Use DO to hold the sum - clear it first
MOVE.B # 2 0 , D l ;There are 20 numbers to add

ADD.B (AO),D0 ;fldci a number to che total in DO


ADD.L # i, ao ;Point to the next number in the list

SUB.B #1,D1 ;Decrement the counter


BNE Next ;Repeat until all added in

IMPORTANT POINTS
The fragment of code to add the 20 numbers is, in principle, confuse operations on a pointer with operations on the
very straightforward. However, it contains aspects that many data elements at which they point!
beginners find confusing. Indeed, I would say that probably
3. Understand the meaning of the # symbol, which indicates
90% of the errors made by beginners are illustrated by this
a literal value, MOVE 1234, DO puts the contents of mem-
fragment of code. Consider the following points.
ory location 1234 in register DO.MOVE #1234, DO puts
1. Data register DO is used to hold the running total. At the the number 1234 in DO. This is the single most common
machine level, registers and memory locations are not set mistake my students make.
to zero before they are used. Therefore, the programmer
4. An address register used to hold a pointer has to be loaded
must initialize their contents either by clearing them or by
with the value of the pointer. This value is a memory
loading a value into them.
location where the data lies. If the symbolic name for the
2. We are working with byte-wide data elements throughout. address of a table is PQR, then you point to PQR with
Therefore all operations on data in this problem have a . B MOVE. L # P Q R , A0. You are putting an actual address in
suffix. All operations on pointers have an . L suffix. Do not A0 and not the contents of a memory location.
5.4 Overview of the 68K's instructions 217

D1 Literal addressing
MOVE #4,D1 4 The operand is part
the instruction.

Memory
D1 Absolute addressing
MOVE 1 2 3 4 , D l The operand is a register
or memory location.

\ Operand 1234

, Memory
Dl Indirect addressing
MOVE (AO),D1 The operand is specified
^ by a pointer. In this case
pointer is in AO.
AO
Pointer
\
Operand

Figure 5.10 The three addressing modes.

Figure 5.10 illustrates these three addressing modes Logical A logical operation treats data as a string of bits and
graphically. performs a Boolean operation on these bits; for example,
11000111 AND 10101010 yields 10000010.
Shift A shift instruction moves the bits in a register one or
5.4 Overview of the 68K's more places left or right; for example, shifting 00000111 one
instructions place left yields 00001110.
Bit A bit instruction acts on an individual bit in a register,
We now look at the type of operations that the 68K and rather than the entire contents of a register. Bit instructions
similar processors carry out on data. Here we are interested in allow you to test a single bit in a word (for 1 or 0), to set a bit,
general principles. In the next chapter we demonstrate how to clear a bit, or to flip a bit into its complementary state.
the instructions can be used. A typical two-operand Compare These instructions compare two operands and set
memory-to-register instruction has the format the processor's status flags accordingly; for example, a
ADD P,D0 compare operation allows you to carry out the test.
Control Control instructions modify the flow of control; that
and is interpreted as [DO] <- [DO] + [P]. The source
is, they change the normal sequential execution of instructions
operand appears first (left to right), then the destination
and permit instructions to be executed out of order.
operand. Instructions can be divided into various categories.
For our current purposes, we will consider the following
broad categories. 5.4.1 Status flags
Data movement These instructions copy data from one Before we continue we have to introduce the notion of the proces-
place to another; for example, from memory to a register or sor status register because its contents can be modified by the
from one register to another. execution of most instructions. The processor status register
Arithmetic Arithmetic instructions perform operations on records the outcome of an instruction and it can be used to imple-
data in numeric form. In this chapter we assume data is either ment conditional behavior by selecting one of two courses of
a signed or an unsigned integer. action. Some processors call this register a condition code register.
218 Chapter 5 The instruction set architecture

Conditional behavior is the feature of computer languages that named because the one thing it does not do is move data. Data
lets us implement high-level language operations such as movement instructions copy data; for example, the instruc-
tion MOVE y , x copies the contents of Y to X but does not
if (x == 4) then
modify the value of Y. You could say that a data movement
or instruction is a data propagate or data copy instruction.
(i = 0; i < 20; i++). Some processors have a load instruction, a store instruc-
tion, and a move instruction. A load copies data from mem-
A processor register contains at least four bits, Z, N, C, and
ory to a register, a store copies data from a register to memory,
V, whose values are set or cleared after an instruction has been
and a move instruction copies data from one register to
executed. These four flags, or status bits, and their interpreta-
another. As we already know, the 68K has a single MOVE
tions are as follows. instruction, which copies data from anywhere to anywhere.
Z-bit Set if the result of the operation is zero. There are other types of move operation; for example, the
N-bit Set if the result is negative in a two's complement 68K has an exchange instruction that swaps the contents of
sense; that is, the leftmost bit is zero. two registers; for example,
C-bit Set if the result yields a carry-out.
EXG Dl, A2 has the effect [A2 ] <- [Dl ] ,- [Al ] <- [A2 ]
V-bit Set if the result is out of range in a two's complement
sense. The purpose of the semicolon in the above RTL indicates
that the two operations happen simultaneously.
Typical CISC processors update these flags after each
operation (see box for more details).
Consider the following example using 8-bit arithmetic. 5.4.3 Arithmetic instructions
Suppose DO contains 001101012 and Dl contains 011000112.
The effect of adding these two values together with Arithmetic operations are those that act on numeric data (i.e.
ADD DO, Dl would result in signed and unsigned integers). Table 5.1 lists the 68K's arith-
00110101 2 metic instructions. Let's look at these in detail.
+01100011 2 Add The basic ADD instruction adds the contents of two
10011000 2 operands and deposits the result in the destination operand.
The result is 100110002, which is deposited in Dl. If we inter- One operand may be in memory. There's nothing to stop you
pret these numbers as two's complement values, we have added using the same source operand twice and writing ADD DO, DO
two positive values and got a negative result. Consequently, the to load DO with the value of 2 X [DO].
V-bit is set to indicate arithmetic overflow. The result is not All addition and subtraction instructions update the con-
zero, so the Z-bit is cleared. The carry-out is 0. The most- tents of the condition code register unless the destination
significant bit is 1, so the N-bit is set. Consequendy, after this operand is an address register.
operation C = 0,Z = 0,N = 1,V = 1. Add with carry The add with carry instruction, ADC, is
almost the same as the ADD instruction. The only different is
5.4.2 Data movement instructions that ADC adds the contents of two registers together with
the carry bit; that is, ADC DO,Dl performs [Dl] <-[Dl] +
The most frequently executed computer operation is data
[DO] + C, where C is the carry bit generated by a previous
movement. The data movement instruction is incorrectly
operation.

CONDITION CODE FLAGS

One of the biggest variations between processor families is Update on demand The condition code register is updated
the treatment of condition code flags .There are three aspects only when the programmer requires it. This mode is indicated
to the way in which these flags are updated. by appending a suffix to an instruction to indicate an update
Update always The condition code flags are updated after flags request.
each and every instruction has been executed. The 68K updates its status bits after most instructions
are executed. You simply have to learn which instrucion
Update sometimes The condition code flags are updated
update the flags and which don't. Instructions that affect
after some instructions have been executed but not others.
the flow of control such as subroutine calls and instructions
Generally the flags are updated after instructions that might
that act on address registers do not update the conditon
be used in a comparison such as 'is X < Y' but not after
code flags.
instructions that perform routine housekeeping tasks.
5.4 Overview of the 68K's instructions 219

Multiplication Unfortunately, two's


ADD D0,D1 Add [Dl] <- [Dl] + [DO] complement arithmetic works only for
ADC D0,D1 Add with carry [Dl] <- [Dl] + [DO] + C
addition and subtraction; that is, you
SUB D0,D1 Subtract [Dl] <- [Dl] - [DO]
don't have to use a different addition
SBC D0,D1 Subtract with carry [Dl] i— [Dl] - [DO] - C
operation for unsigned and signed inte-
MULU D 0 , D 1 Multiply (unsigned) [Dl] <r- [Dl] X [DO]
Multiply (signed) gers. The same is not true for multipli-
MULS D 0 , D 1 [Dl] <- [Dl] X [DO]
DIVU D 0 , D 1 Divide (unsigned) [Dl] <- [Dl] H- [DO]
cation and division. If you are using
DIVS D 0 , D 1 Divide (signed) [Dl] <~ [Dl] ^ [DO] unsigned integers you have to do multi-
plication one way and if you are using
signed two's complement integers you
Table 5.1 The 68K's arithmetic instructions.
have to do multiplication in a different
way. Consequently, the 68K has two
Most-significant word Least-significant word
multiplication (and division) instruc-
The two lower words are
^lower added to generate a sum
tions and you have to choose the one to
^upper
and a carry out. reflect the type of numbers you are
1 'lower The two higher words are
using. MULU multiplies two unsigned
upper
added together with any integers and MULS multiplies two signed
carry bit generated from
adding the low-order words.
integers.
The 68K's multiplications do not
"-upper Mower
provide the same flexibility as the 68K's
addition instructions. You can multiply
Figure 5.11 Extended addition.
only two 16-bit integers to get a 32-bit
result (remember that multiplying two n-bit values yields a
2«-bit product). The operation MULU DO, Dl performs the
This instruction is used in extended or compound arith- operation
metic. Suppose you wish to add two 64-bit numbers using
[Dl, 0:31 [01,0:15)1 X [DO,0:15)]
the 32-bit 68K. Assume that the most-significant 32 bits of X
are in DO and the least-significant 32 bits are in Dl, and the
most-significant 32 bits of Y are in D2 and the least-signifi- Division The 68K's division instructions are a little more
cant bits are in D3. We can perform the 64-bit addition complicated because division results in a quotient plus a
X + Yby remainder; for example, 17 + 3 = 5 remainder 2. The 68K

ADD.L D0,D2 ;Add the low-order 32 bits, update carry flag


ADC.L D1,D3 ;Add the high-order 32 bits plus any carry

In this example we use ADD . L to add the two low-order 32- divides a 32-bit value by a 16-bit value to produce a 16-bit
bit words. Remember that the . L suffix indicates a 32-bit quotient and a 16-bit remainder. In order to avoid using an
operation. An addition records any carry bit generated by the instruction with three operands, the quotient and remainder
addition and moves it to the C-bit. The following instruction are packed in the same register. For example, DIVU DO, Dl
ADC adds the high-order longwords together with any carry divides the 32-bit contents of Dl by the 16-bit lower-order
that was generated by adding the low-order longwords. 16-bit word in DO and puts the 16-bit quotient in the low-
Figure 5.11 illustrates the addition Z = X + Y where X, Y, order word of D1 and the 16-bit remainder in the high-order
and Z are 64-bit values and the addition is to be performed word of Dl. We can express this as
with 32-bit arithmetic. Each of the operands is divided into
an upper and lower 32-bit word.
[01,0:15)1 [Dl(0:31)l ^ [D0,0:15)]
Subtract The subtract instruction subtracts the source [01,15:31)1 remainder
operand from the destination operand and puts the result in
the destination register; for example, SUB DO, Dl performs
[Dl]«-[Dl] - [DO]. A special subtraction operation that If DO contains 4 and Dl contains 1234516, the operation
facilitates multiple length subtraction, SBC DO , Dl, performs DIVU DO, Dl results in Dl = 000148D116. Consider the fol-
the action [D1]<-[D1] - [DO] - C (the carry bit is also lowing fragment of code where we divide P by Q and put the
subtracted from the result). quotient in D2 and the remainder in D3.
220 Chapter 5 The instruction set architecture

MOVE.L P,D1 ;get P


MOVE.W Q,DO ;get Q
DIVU D0,D1 /divide P by Q
CLR.L D2 /clear D2 ready to receive quotient
MOVE.W D1,D2 /put quotient in D2
CLR.L D3 /clear D3 ready to receive remainder (clear = make 0)
SWAP Dl /exchange upper and lower words in Dl
MOVE.W D1,D3 /put remainder in D3

This code is more complex than you would think and depending only on the outcome of the comparison. Here we
demonstrates the pitfalls of assembly language. First we have to simply demonstrate a (compare, branch) pair because we will
remember that P is a 32-bit value and that Q is a 16-bit value. soon look at branch instructions in greater detail.
The divide instruction divides a 32-bit value by a 16-bit value. Consider the high-level construct i f (x = = 5 )
Because we get the quotient and remainder in Dl, we have to {x = x + 10}
split them and copy them to D2 and D3 respectively. A MOVE We can write the following fragment of code:
instruction always operates on the low-order word in a register, MOVE X,D0 / g e t X i n DO
which means that we don't have to worry about the remainder CMP #5,DO / i s X == 5?
BNE Exit / i f n o t e q u a l t h e n go t o "exit"
bits in bits 16 to 31 of D1 when we copy the quotient. However, ADD #10,DO / e l s e a d d 10 t o X
because D2 is a 32-bit register, we should ensure that the upper MOVE D0,X / r e s t o r e X t o memory
order bits are zero before we do the transfer. We use CLR . L to set Exit .
all the bits of D2 to zero before transferring the 16-bit quotient.
In this example the branch instruction BNE E x i t forces a
We can use the SWAP instruction, which exchanges the
branch (jump) to the line labeled by E x i t if the outcome of
upper and lower order words of a register to get the remain-
the compare operation yields 'not zero'.
der in the low-order 16-bits of Dl before we transfer the
remainder to D3.
When writing 68K instructions, you always have to ask
5.4.5 Logical instructions
yourself'How? many bits are we operating on? and' What are
we going to do about the bits not taking part in the operation1. Logical operations allow you to directly manipulate the indi-
Some processors take away that choice; for example, the ARM vidual bits of a word. When a logical operation is applied to
and similar RISC processors require that all operations be two 32-bit values, the logical operation is applied (in parallel)
applied to all bits of a register. to each of the 32 pairs of bits; for example, a logical AND
between A and B would perform q = a{b{ for all values of i.
Table 5.2 illustrates the 68K's logical operations using an 8-
5.4.4 Compare instructions bit example.
High-level languages provide conditional constructs of the form The AND operation is dyadic and is applied to two source
if (x == y) {a = b * c } /
operands. Bit i of the source is ANDed with bit i of the desti-
nation and the result is stored in bit i of the destination. If
We examine how these constructs are implemented later. [Dl] = 110010102, the operation
At this stage we are interested in the comparison part of the
AND #»11110000,D1
above construct, (x = = y ) , which tests two variables for
equality. We can also test for greater than or less than. The results in [Dl] = 110000002. Remember that the symbol #
operation that performs the test is called comparison. indicates a literal or actual operand and the symbol %
The 68K provides a compare instruction CMP s o u r c e , indicates a binary value. We can represent this operation
d e s t i n a t i o n , which evaluates [Rd]-[Rs] and updates the more conventionally as
bits in the condition code register accordingly.
11001010
A compare instruction is inevitably followed by a branch 11110000
instruction that chooses one of two courses of action 11000000

D2 Dl Operation Processor status flags


10101010 10101010 CMP D1,D2 Z = 1,C = 0,N = 0,V = 0
10101010 00000000 CMP D1,D2 Z = 0,C = 0,N = 1,V = 0
10101010 11000001 CMP D1,D2 Z = 0,C= 1,N= 1,V = 0
5.4 Overview of the 68K's instructions 221

Mnemonic Opera t ion Definition Example


AND DO, D l Logical AND [D1] <- [D1] A [DO] 11110000 • 10101010 = 10100000
OR D0,D1 Logical OR [D1] <-[D1] v [DO] 11110000 + 10101010 = 11111010
EOR DO, D l Exclusive EOR [D1] +- [D1] e [DO] 11110000 e 10101010 = 01011010
NOT D l Logical NOT [D1]<-fDlJ 11110000 = 00001111

Table 5.2 The 68K's logical instructions.

The AND operation is used to mask the bits of a word. If 5.4.7 Shift instructions
you AND bit x with bit y, the result is 0 if y = 0, and x if/ = 1.
A typical application of the AND instruction is to strip the A shift operation moves a group of bits one or more places
parity bit off an ASCII-encoded character. That is, left or right; for example, consider the following examples
AND #%01111111,D1
Source After shift left After shift right
clears bit 7 of Dl to zero and leaves bits 0 to 6 unchanged.
The OR operation is used to set one or more bits of a word 00110011 01100110 00011001
to 1. ORing a bit with 0 has no effect and ORing the bit with 11110011 11100110 01111001
1 sets it. For example, if [Dl] = 110010102, the operation 10000001 00000010 01000000
OR #%11110000,D1
Although there are only two shift directions, left and right,
results in [Dl] = 111110102. there are several variations on the basic shift operation. These
The EOR operation is used to toggle (i.e. invert) one variations depend on whether we are treating the value being
or more bits of a word. EORing a bit with 0 has no effect shifted as an integer or a signed value and whether we include
and EORing it with 1 inverts it. For example, if [Dl] = the carry bit in the shifting.
110010102, the operation Shift operations are used to multiply or divide by a power
EOR #%11110000,D1 of 2, to rearrange the bits of a word, and to access bits in
a specific location of a word.
results in [Dl] =00111010 2 .
Figure 5.12 illustrates the various types of shift operation.
By using the NOT, AND, OR, and EOR instructions, you
Suppose the 8-bit value 110010102 is shifted one place right.
can perform any logical operations on a word. Suppose you
What is the new value? A logical shift right operation, LSR
wish to clear bits 0,1, and 2, set bits 3,4, and 5, and toggle bits
introduces a zero into the leftmost bit position vacated by the
6 and 7 of the byte in DO. You could write
shift and the new value is 011001012.
AND #%11111000,D1 C l e a r b i t s 0, 1, and 2 Arithmetic shifts treat the data shifted as a signed two's
OR #%00111000,D1 S e t b i t s 3, 4, and 5 complement value. Therefore, the sign bit is propagated by
EOR #%11000000,D1 T o g g l e b i t s 6 and 7 .
an arithmetic shift right. In this case, the number
If [Dl ] initially contains 010101012, its final contents will 110010102 = —54 is negative and, after an arithmetic right
be 101110002. We will look at a more practical application of shift, ASR, the new result is 111001012 (i.e. - 2 7 ) .
bit manipulation after we have covered branch operations in When a word is shifted right, the old least-significant bit
a little more detail. has been shifted out and 'lost'. Figure 5.12 shows that this bit
isn't lost because it's copied into the carry flag bit.
An arithmetic shift left is equivalent to multiplication by 2
5.4.6 Bit instructions
and an arithmetic shift right is equivalent to division by 2.
The 68K provides bit instructions that operate on the indivi- Some computers allow you to shift one bit position at a
dual bits of a word. Bit instructions are not strictly necessary, time. Others let you shift any number of bits. The number of
because you can use logical operations to do the same thing. bits to be shifted can be a constant; that is, it is defined in the
The 68K's bit instructions can be used to set, clear, or toggle program and the shift instruction always executes the same
(complement) a single bit in a word. Moreover, the bit instruc- number of shifts. Some computers let you specify the
tions also test the state of the bit they have tested and set or clear number of bits to be shifted as the contents of a register. This
the Z-bit of the condition control register accordingly. Consider allows you to implement dynamic shifts because you can

BTST #4,DO ;test bit number 4 of DO and set the Z-bit accordingly
BSET #4,DO ;test bit 4 of DO, se the Z-bit accordingly, set bit 4
BSET D1,D0 ;test the bit of DO w iose position is in Dl
222 Chapter 5 The instruction set architecture

LSL
Logical shift left

H Operand 4 4 0 A zero enters the least-significant bit and the


most-significant bit is copied to the carry flag.

LSR
Logical shift right
0 • Operand •
•B A zero enters the most-significant bit and the
least-significant bit is copied to the carry flag.

ASL
Arithmetic shift left

0- Operand •+- •* 0 A zero enters the least-significant bit and the


most-significant bit is copied to the carry flag.

ASR Arithmetic shift right

MSB Operand •
•H The old most-significant bit is copied into the new
most-significant bit and the least-significant bit is
copied to the carry flag.

ROL
Rotate left

LH -4 * Operand

ROR
-*- The most-significant bit is copied into the
least-significant bit and the carry flag.

Rotate right
Operand :U[7| The least-significant bit is copied into the
most-significant bit and the carry flag.

ROLC

0 A » Operand

RORC
-4-
s Rotate left through carry
The most-significant bit is copied into the carry flag
and the old C-bit copied into the least-significant bit.

Rotate right through carry


Urn- -•I Operand
^B The least-significant bit is copied into the C flag
and the old C-bit copied into the most-significant bit.

Figure 5.12 The four classes of shift instruction.

change the contents of the register that specifies the number Shift type Before circular shift After circular shift
of shifts. The 68K lets you write LSL #4, DO to shift the con- Rotate left, ROL 11001110 10011101
tents of data register DO left by four places or LSL Dl, DO to Rotate right, ROR 11001110 01100111
shift the contents of DO left by the number in Dl.
Figure 5.12 also describes circular shifts or rotates. A circ- The last pair of shift operations in Fig. 5.12 are called rotate
ular shift operation treats the data being shifted as a ring with though carry. These operations treat the carry bit as part of
the most-significant bit adjacent to the least-significant bit. the shift operation. A circular shift is performed with the old
Circular shifts result in the most-significant bit being shifted carry bit being shifted into the register and the bit lost from
into the least-significant bit position (left shift), or vice versa the carry register being shifted into the carry bit. Suppose that
for a right shift. No data is lost during a circular shift. the carry bit is currently 1 and that the 8-bit value 111 100002
Consider the following examples. is to be shifted one place right through carry. The final result
5.4 Overview of the 68K's instructions 223

is 111110002 and the carry bit is 0. A circular shift is a non- ROXR The operand is rotated by 0 to 31 places right. The bit
destructive shift because no information is lost (bits don't fall shifted out of the least-significant end of the operand is
off the end). shifted into the C-bit. The old value of the C-bit is copied into
The 68K's shift instructions are as follows. the most-significant end of the operand; that is, shifting takes
place over 33 bits (i.e. the operand plus the C-bit).
LSL The operand is shifted left by 0 to 31 places. The vacated
bits at the least-significant end of the operand are filled with Shift operations can be used to multiply or divide a num-
zeros. ber by a power of two. They can be used for several other pur-
LSR The operand is shifted right 0 to 31 places. The vacated poses such as re-arranging binary patterns; for example,
bits at the most-significant end of the operand are filled with suppose register D2 contains the bit pattern Oaaaaxxxbbbb,
zeros. and we wish to extract the xxx field (we're using 12-bit arith-
metic for simplicity). We could write
ASL The arithmetic shift left is identical to the logical
shift left. LSR #4,D2 ;this will give us OOOOOaaaaxxx

ASR The operand is shifted right 0 to 31 places. The vacated If we want to ensure that we just have the xxx field, we can use
bits at the most-significant end of the operand are filled with a logical AND to clear the other bits by
zeros if the original operand was positive, or with Is if it was AND #%111,D1 ; t h i s w i l l g i v e us OOOOOOOOOxxx
negative (i.e. the sign-bit is replicated). This divides a number
by 2 for each place shifted.
ROL The operand is rotated by 0 to 31 places left. The bit 5.4.8 Branch instructions
shifted out of the most-significant end is copied into the
A branch instruction modifies the flow of control and causes
least-significant end of the operand. This shift preserves all
the program to continue execution at the target address speci-
bits. No bit is lost by the shifting.
fied by the branch. The simplest branch instruction is the
ROR The operand is rotated by 0 to 31 places right. The bit unconditional branch instruction, BRA t a r g e t , which
shifted out of the least-significant end is copied into the always forces a jump to the instruction at the target address.
most-significant end of the operand. This shift preserves all In the following fragment of code, the BRA Here instruction
bits. No bit is lost by the shifting.
BRA Here ;jump to the line that begins "Here"
ROXL The operand is rotated by 0 to 31
places left. The bit shifted out of the most
significant end of the operand is shifted
into the C-bit. The old value ofthe C-bit is Here ADD R0,D1
copied into the least-significant end ofthe
operand; that is, shifting takes place over 33 bits (i.e. the forces the 68K to execute next the instruction on the line
operand plus the C-bit). which is labeled by Here.

1000 Instruction 1
1004 Instruction 2
1008 Instruction 3
100C Instruction 4
1010 Instruction 5
1014 Instruction 6 The branch instruction forces the
instruction at 2000 to be executed
1018 Instruction 7
next.
101C Instruction 8 ' BRA 2000
1020 Instruction 9 >2000 Instruction N
1024 Instruction 10 2004 Instruction A/+ 1
1028 Instruction 11 2008 Instruction N+2
102C Instruction 12 200c Instruction N+ 3
1030 Instruction 13 2010 Instruction /V+4
1034 Instruction 14 -BRA 1040 2014 Instruction A/+ 5
1038 Instruction 15
103C Instruction 16
1040 Instruction 17
1044 Instruction 18 ,
I
Figure 5.13 The unconditional branch.
224 Chapter 5 The instruction set architecture

1000 Instruction 1 Instruction 8 is BEQ 2000 and is interpreted


1004 Instruction 2 as 'branch to instruction N if die last result was
1008 Instruction 3
When instruction 8 is executed,
zero, odierwise continue'. Consequendy, there
100C Instruction 4
the next instruction is at 1020 if is a fork at instruction 8 between the path if the
1010 Instruction 5
the condition is false and 2000 if the last result was not zero and a path (to instruc-
1014 Instruction 6
condition is true.
1018 Instruction 7 tion N) if the result was zero.
1 o 1C <TnSrucrJon8 EEQ We can imagine that the test for zero leads
False True to the execution of code block 1 or code block
X^ Block 1 Block 2 2. At the end of code block 2 a branch back to
1020 Instruction 9 Instruction N the main stream of instructions is made.
2000
1024 Instruction 10 2004 Instruction N+1 Let's look at this conditional behavior in
1028 Instruction 11 2008 Instruction N +2 high-level language. Consider the following
102C Instruction 12 200c Instruction N+3
1030 Instruction 13 example of the high-level construct
2010 Instruction N +4
1034 Instruction 14 2014 Instruction N+ 5 T
1038 Instruction 15 B 1040 if (x 3) t h e n y
103C Instruction 16 ^r
We can translate this construct into the
following 68K code.
1040 Instruction 17
CMP #3,D1 ;<x == 3>?
1044 Instruction 18
BNE exit ; if x is not 3 then leave
MOVE #4,D2 ;if x is 3 then y - 4
Figure 5.14 The conditional branch. exit . . .

The instruction CMP #3 , Dl compares the


Mnemonic Condition Flags
contents of register Dl with the literal 3 by
BEQ equal Z= 1 evaluating [Dl] — 3 and setting the status
BNE not equal Z= 0
flags. If the result of the operation is zero, the
BCS/BHS carry set/higher or same C= 1
BCC/BLO carry clear/lower C= 0
Z-bit is set to 1. If the result is not zero (i.e.
BMI negative N = 1 Dl does not contain 3), the Z-bit is set to 0.
BPL positive or zero N = 0 The key instruction is BNE e x i t , which
BVS overflow set V= 1 means 'branch on not zero to the instruction
BVC overflow clear V = 0 labeled exit'. The effect of this instruction is
BHI higher than (signed) (C = 1).(Z = 0) to test the Z-bit of the status flags and then
BLS lower or same (signed) (C = 0)+(Z = 1)
branch to the instruction with the label 'exit'
BGE greater than or equal (signed) N = V
if Z = 0 (i.e. Dl is not 3). If Dl is 3, Z = 1,
BLT less than (signed) N*V
BGT greater than (signed) (Z = 0).( N = V)
the branch is not taken, and the MOVE #4, D2
BLE less than or equal (signed) (Z= 1 ) + ( N * V ) instruction is executed.
The 68K provides 16 branch instructions of
Table 5.3 The 68K's conditional branches. the form Bcc where CC defines the branch condition. These
16 conditions, described in Table 5.3, are virtually die same
as tiiose provided by many other microprocessors. We will see
Figure 5.13 demonstrates how an unconditional branch what the 4 bits in the first column mean later.
can modify the flow of control. In this example, execution Let's look at another application of conditional branching.
continues sequentially from instruction 1 to instruction 8, You can implement a loop construct in the following way
which is BRA 2 000 (branch to instruction N at location
MOVE #20, DO ,-load the loop counter DO with 20
200016). The address of the first instruction is 100016 and each Next ;body of loop
instruction takes 4 bytes. Execution then continues with the
instruction at location N. Instruction N + 5 is BRA 1040
SUB #1,D0 ;decrement loop counter
(branch to instruction 17 at location 104016) and a change of BNE Next ;repeat until loop count = zero
flow takes place again.
The most important feature of any computer is its abil- Let's look at another example of the use of branching.
ity to implement conditional behavior by carrying out a Suppose A and B are two n-component vectors. As we have
test and then branching on the result of the text. already stated, the inner product of A and B is the scalar value
Figure 5.14 demonstrates the flow of control with a condi- s = A B = a^b, + a2-b2 + a 3 b 3 . . . a n b n . We can now
tional branch. write the code
5.4 Overview of the 68K's instructions 225

CLR.L D6 clear initial sum in D6


MOVE #24,D5 load loop counter with n (assume 24 here)
MOVE.L #A,AO AO points at vector A
MOVE.L #B,A1 Al points at vector B

Next MOVE (AO),D2 Repeat: get At and update pointer to A


ADD.L #2,A0 point to next element in A
MOVE (A1),D3 get Bi and update pointer to B
ADD.L #2,A1 point to next element in B
MULU D2,D3 Ai x Bi
ADD.L D3,D6 s = s + Ai x Bi
SUB #1,D5 decrement loop counter
BNE Next repeat n times

Subroutine calls Code


A subroutine is a piece of code that is called and executed and
a return is made to the calling point. Subroutines are very
important because they implement the function or procedure Subroutine
at the high-level language level. We look at subroutines in Call
more detail in the next chapter. Here we are interested only in
the principle of the subroutine call and return. "\Return
Figure 5.15 demonstrates the subroutine call. Code is exe-
cuted sequentially until a subroutine call is encountered. The
current place in the code sequence is saved and control is then
transferred to the subroutine; that is, the first instruction in
the subroutine is executed and the processor continues exe-
Figure 5.15 The subroutine call.
cuting instructions in the subroutine until a return instruc-
tion is encountered. Then, control is transferred back to the
point immediately after the subroutine call by retrieving the . Set up a parameter in DO
saved return address. MOVE.W # 4 , D O -
BSR ABC •
Figure 5.16 illustrates this concept with a simple subroutine • The subroutine call
2
called ABC that calculates the value of Ix (where x is a 16-bit
value passed in DO). This subroutine is called by the instruction Return point
(next instruction after
BSR ABC (branch to subroutine), and a return from subroutine the subroutine)
is made by an RTS (return from subroutine) instruction.
ABC MULU DO, DO
Figure 5.17 displays the program of Fig. 5.16 in the form of ASL.L #1,D0 — The subroutine
a memory map and demonstrates the flow of control RTS * - • Return from subroutine
between the calling program and the subroutine ABC.
Figure 5.18 extends the example in Fig. 5.15 by demon- Figure 5.16 The subroutine.
strating a multiple call. We have used the instruction
BSR ABC to implement the subroutine
call. The main body of the code calls
Body of the code
subroutine ABC. At the end of the sub-
routine, a return instruction makes a
MOVE.W # 4 , DO
return to the instruction following the
calling point. As you can see, the subrou- BSR ABC —~• Subroutine
tine is called from two different places
and yet a return is made to the correct ABC MULU DO,DO
point in each case.
ASL.L #l,DO
In chapter 6 we look at how assembly
language programs are constructed. We ~~~""~- RTS Return
will also look at a data structure called
the stack, which is used to hold subrou-
tine return addresses. Figure 5.17 Memory map of a subroutine call and flow of control.
226 Chapter 5 The instruction set architecture

5.5 What's a register-to-register


architecture and why is such an
architecture also called a load and store
BSR ABC F,v5* „ „ . Subroutine
computer?
N
5.6 What are the three fundamental
N
* ^ ^ ^ addressing modes? Are they all
necessary? What is the minimum number
Return of addressing modes required? Can you
BSR ABC - " seco^ 0 ^ ^^______ • think of other possible addressing
6 modes?
M .. i ^ ^ ^ '
5.7 The 68K has two add instructions:
ADD and ADC. What is the difference
between them? If the processor lacked
Figure 5.18 Multiple subroutine calls.
an ADC instruction, how would you
synthesize it (i.e. what other instructions would you use to
achieve the same effect)?

II SUMMARY 5.8 The 68K has an exchange registerpa/r instruction, EXG.


Why would you want such an instruction?
We have introduced the CPU and its native language, the 5.9 The SWAP D i instruction swaps the upper- and lower-order
assembly language, which is a human-readable representation words of data register Di. Why would you want such an
of machine code. Unfortunately, assembly languages are not instruction? If the 68K's instruction set lacked a SWAP, how
portable; each family of microprocessors has its own unique would you swap the two halves of a data register?
assembly language that is incompatible with any other
processor. You can run a C program on most computers with a C 5.10 Why are so many variations on a shift operation provided
compiler.A program written in Pentium assembly language will by the 68K and many other processors?
run only on machines with a Pentium at their core. 5.11 What is the largest memory space (i.e. program) that can
We introduced the concept of an architecture, the assembly be addressed by processors with the following number of
language programmer's view of the computer in terms of its address bits?
functionality rather than performance or implementation. To (a) 12 bits
illustrate the characteristics of an architecture we selected the (b) 16 bits
elegant 68K processor, which is, paradoxically, simpler than (c) 24 bits
many of its contemporaries while, at the same time, (d) 32 bits
incorporating a number of sophisticated facilities such as the (e) 48 bits
ability to shift an operand as part of a data processing (f) 64 bits
instruction and the ability to execute an instruction only if
certain conditions are met (predication). 5.12 The von Neumann stored program computer locates
An architecture consists of a set of instructions, a set of program and data in the same memory. What are the
resources (the registers), and the addressing modes used to advantages and disadvantages of a system with a combined
access data. program and data memory?
In this chapter we have laid the foundations for the next 5.13 The gear lever is part of an automobile's organization
chapter where we look at how programs can be constructed to rather than its architecture. Are the brakes part of a car's
run on the instruction set architecture we introduced here. architecture or organization?
5.14 What does the RTL expression [ 1 0 0 ] < - [ 5 0 ] + 2 mean?
M PROBLEMS 5.15 What does the RTL expression [ 1 0 0 ] < - [ 5 0 + 2 ] + 2
mean?
5.1 What's the difference between an assembly language and
machine code? In order to answer this question fully, you should 5.16 What is an operand?
use the Internet to find out more about assemblers. 5.17 In the context of an instruction register, what is a field?
5.2 Books and articles on the computer make a clear distinction 5.18 What is a literal operand?
between architecture and organization. Do you think that this is a 5.19 What is the effect on the C-.V-, Z-, and N-bits when the
useful distinction? Can you think of other areas (i.e. non-computer following 8-bit operations are carried out?
example) where such a distinction would be appropriate?
5.3 What are the advantages and disadvantages of dividing a (a) 01110001 (b) 11110101 (c) 10100011
computer's registers into data and address registers like the 68K?
+01111001 +11000111 +01011101

5.4 What are the relative advantages and disadvantages of one- 5.20 Some microprocessors have one general-purpose data
address, two-address, and three-address instruction formats? register, some two, some eight, and so on. What determines the
5.4 Overview of the 68K's instructions 227

number of such general-purpose data registers in any given 5.31 What is the difference between the C, Z, V, and N flags in a
computer? computer's status register (or condition code register)?
5.21 What is the difference between a dedicated and a general- 5.32 What is the difference between machine code and
purpose computer? assembly language?
5.22 What is a subroutine and how is it used? 5.33 What is the advantage of a computer with many registers
5.23 What is the so-called von Neumann bottleneck? over one with few registers?
5.24 For the following memory map explain the meaning of the 5.34 Translate the following algorithm into assembly language.
following RTL expressions in plain English. I F X > 12 THEN X = 2*X + 4 ELSE X = X + Y

(a) [1000] = 120 5.35 For the memory map below, evaluate the following
(b) [1003] = [1001] + 1 expressions, where [N] means the contents of the memory
(c) [1004] <- 5 location whose address is N. All addresses and their contents are
(d) [1000] <- [1005] decimal values.
(e) [1001] <- [1002] + [ 1 0 0 3 ]
(f) [1000] <- [ 1 0 0 3 + 1]
00 12
01 17
1000 120
02 7
I00I 1003
1002 8 03 4
1003 1004 04 8
1004 0 05 4
1005 23 06 4
07 6
08 0
5.25 Suppose a problem in a high-school algebra text says 'Let
x= 5'. What exactly is x? Answer this question from the point 09 5
of view of a computer scientist. 10 12
5.26 In the context of a CPU, what is the difference between a 11 _ 7
data path and an address path? 12 6
5.27 Why is the program counter a pointer and not a counter? 13 3
5.28 What's the difference between a memory location and a 14 2
data register?
5.29 Does a computer need data registers?
(a) [7] (f) [ [ 9 ] + [2]]
5.30 Some machines have a one-address format, some a
two-address format, and some a three-address format; for (b) [[[4]] (g)[[5] + [13] + 2*[14]]
example, (c) [[[0}]]] (h) [ 0 ) ] ' 3 + [ 1 ] * 4
(d) [2 + 10] (i) [ 9 ] * [10]
ADD PI
ADD P 1 , P 2 (e) [[9] + 2]
ADD P 1 , P 2 , P 3
5.36 The most frequently executed class of instruction is the
What are the relative merits of each of these instruction formats? data move instruction. Why is this?
Assembly language programming
CHAPTER MAP

5 The instruction set 6 Assembly language 7 Structure of the CPU 8 Other processors •..:
architecture programming Now we know vvftat a computer We have used the 68K to
' Chapter 5 introduces the does, the next step is to show • introduce the CPU and assembly
Having introduced the basic
computer's instruction set . /low it operates, fn Chapter 7 we language programming. Here we •
operations that a computer can
architecture, which defines the examine the internal provide a brief overview of some •
carry out, the next step is to
tow-level programmer's view of • organization of a computer and of the features of other ••..
show how instructions are used
the computer and describes the ' demonstrate how it reads, processors.
to construct entire programs. We
type of operations a computer, instructions from memory,
introduce the 68K's
carries out. We are interested in decodes them, and executes '
programming environment via a
three aspects of the ISA: the •' them: •
simulator that runs on a PC and
nature of the instructions, the
demonstrate how to implement
resources used by the
some basic algorithms.
instructions (registers and
memory), and the way in which
the instructions access data
(addressing modes).

INTRODUCTION
We introduced the processor and its machine-level language via the 68K CISC processor in the previous
chapter. Now we demonstrate how 68K assembly language programs are written and debugged.
Because assembly language programming is a practical activity, we provide a 68K cross-assembler
and simulator with this book. Previous editions of this book used the DOS-based Teesside simulator.
In this edition we use a more modern Windows-based system called Easy68K.We provide a copy of
the EASy68K simulator on the CD accompanying this book, as well as a copy of the Teesside
simulator and its documentation for those who wish to maintain compatibility with earlier editions.
Both simulators run on a PC and allow you to execute 68K programs. You can execute a program
instruction by instruction and observe the effect of each instruction on memory and registers as it
is executed.

the mnemonic and its operand must be separated by at least


6.1 Structure of a 68K assembly one space and that no embedded spaces may be located
language program within either the mnemonic or operand fields.
Recall that numbers prefixed by the $ symbol are hexadec-
Figure 6.1 provides the listing of a simple assembly language imal, whereas numbers prefixed by % indicate that the fol-
program written to run on the 68K cross-assembler. This lowing number is expressed in binary form; for example, tiie
program implements the high-level language operation following three instructions
R = P + Q (where variables P = 2 and Q = 4). Few rules gov-
ern the layout of a 68K assembly language program. The left- MOVE 25,DO load DO with 25i0
MOVE $19,DO load DO with 2510
most column is reserved for user-defined, labels—in this case,
MOVE %11001,D0 load DO with 2510
P, Q, and R. If a line begins with an asterisk in the first col-
umn, the assembler ignores the rest of the line. You put an are equivalent. The assembler translates each of these into
asterisk in column 1 to create a comment. Another rule is that exactly the same machine code.
6.1 Structure of a 68K assembly language program 2 2 9

THE 68K ARCHITECTURE REVIEW

The 68K has 16 general-purpose 32-bit user accessible an address register always yield a 32-bit value whereas
registers. DO to D7 are data registers and AO to A7 are address operations on data registers can be 8,16, or 32 bits.
registers. An address register holds a pointer and is used in Most 68K instructions are register to register, register to
address register indirect addressing. The only instructions that memory, or memory to register. The following defines some
can be applied to the contents of address registers are add, 68K instructions.
subtract, move, and compare. Operations on the contents of

MOVE.B D0,D1 Copy the low-order byte in DO to D1 (0:7) .


MOVE.W ABC,D1 Copy the 16-bit word in memory location ABC to D1(0:l5).
MOVE.L DO, (AO) Copy the 32-bit value in DO to the memory location pointed at by address register AO.
ADD . B D l , ABC Add the low-order byte in register D1 to the contents of memory location ABC.
SUB.B # 4 , (A3) Subtract 4 from the contents of the byte-wide memory location pointed at by A3.
ADD. L A l , D5 Add the 32-bit contents of address register A1 to data register D5.
The # symbol indicates the immediate addressing mode; that is, the operand is a literal value.

.ORG $1000 ^ _ _ 6 8 K machine


level i n s t m c t l 0 n
An asterisk in fri^TE? H~i^>*-—-—""""^
the first column /(gOVE P , D Q ) * - ^ _ ^ ^
indicates the line /CADD) QfOO^_ operand
is a comment / \ ^ r „ ~~x ——___
\ / MOVE\CD0_,_Rj) ^^Destination
\^ / STOP \ # $ 2 7 00 \ . operand
* T h i s i s t h e en\l o f t h e c e d e a r e a
/ <ORG $2^00 \ ^„T h.i s .is an operand
T \ -This \s an operand
that describes the
P / /4 D C . W 2 \ data
that describes
to the CPUthe
d a t a t ot h e C P U
Q / // DC. W 4 \ This is a mnemonic
XR/ //Arf'-'SuWj 1 .„ that describes
This is the
a mnemonic
/"-'I /// / r.»ir^^ t 1 n n n that describ
operation toes
bethe
/ / / / / / '\$1000 o pe rati
o n
carried outt 0 b e
,/ / ///// ^ x carried out

Label / / / / / A
A .. W suffix indicates that
Assembler directives the
the data size is 16 bits
(these directives tell the assembler 'Figure 6.1 Structure of an assembly
things it needs to perform its job) Ilanguage program.

Figure 6.2 shows the structure of a typical 68K instruction. We've already encountered the first three instructions. The
Instructions with two operands are always written in the last instruction, STOP #$2700, terminates the program by
form s o u r c e , d e s t i n a t i o n , where s o u r c e is where the halting further instruction execution. This instruction also
operand comes from and d e s t i n a t i o n is where the result loads the 68K's status register with the value 270016, a special
goes to. code that initializes the 68K. We use this STOP instruction to
terminate programs running on the simulator.
An assembler directive tells the assembler something it needs
6.1.1 Assembler directives
to know about the program; for example, the assembler direc-
Assembly language statements are divided into executable tive ORG means origin and tells the assembler where instruc-
instructions and assembler directives. An executable instruction tions or data are to be loaded in memory. The expression
is translated into the machine code of the target microproces- ORG $ 10 0 0 tells the assembler to load instructions in memory
sor and executed when the program is loaded into memory. In
the example in Fig. 6.1, the executable instructions are
Remember that in the instruction STOP # $ 2 7 0 0 the operand
is # $ 2 7 0 0 . The '#' indicates a literal operand and
MOVE P,D0 Copy contents of P to DO the '$' indicates hexadecimal. The literal operand
ADD Q,D0 Add contents of Q to DO 00100111000000002 is loaded into the 68K's status
MOVE D0,R Store contents of DO in memory location R register after it stops. The 68K remains stopped until it it
STOP #$2700 Stop executing instructions1 receives an interrupt.
230 Chapter 6 Assembly language programming

.Edge of screen/paper (column 1)


The first operand, P, defines the
;A source of the data used by the instruction.
The fields of an instruction are In this case the source is the contents
separated by at least one space of a memory location

istart MOVE.B P,D0 GetP


t DO is the destination Anything following the
operand (in this case instruction is treated as a
a data register) comment and ignored
Anything beginning in by the assembler
column 1 is a user-supplied
label that allows the This is a mnemonic
programmer to refer to that indicates the
instruction to be Many instruction are terminated by
this line . B . W or . L. These suffixes define
carried out
the size of the operand (byte,
world, or longword)

Figure 6.2 Anatomy of an assembly language instruction.

starting at address 100016. We've used the value 100016 because Figure 6.3 demonstrates what's happening when the 68K
the 68K reserves memory locations 0 to 3FF16 for a special pur- program in Fig. 6.1 is assembled by looking at the output pro-
pose and 1000 is an easy number to remember. duced by EASy68K. This listing has seven columns. The first
The second origin assembler directive, ORG $2000, is column is a 32-bit value expressed in hexadecimal form,
located after the code and defines the starting point of the which contains the current memory address in which
data area. We don't need this assembler directive; without it instructions or data will be loaded. The next two columns are
data would immediately follow the code. WeVe used it the hexadecimal values of instructions or data loaded into the
because it's easy to remember that the data starts at memory current memory location. These are the values produced by
location $2000. the assembler from instructions, addresses, and data in the
An important role of assembler directives is in reserving assembly language program. The fourth column contains the
memory space for variables, presetting variables to initial val- line number that makes it easy to locate a particular line in
ues, and binding variables to symbolic names. Languages like C the program. The remaining right-hand columns in Fig. 6.3
call these operations declaring variables. We will be performing are the instructions or assembler directives themselves
assembly level actions similar to the following C declarations. followed by any comment field.

int • • time; •;' ,/t- declare integer "time" -.' /. */


i n t x,. y; /* declare two integers- x and y
' . • • • ' • • ' */
.int ' 23 := ;42; •' - /* declare an integer z3 and assign the value 42 */
':char:/tefin.-= ;*/@' ';•• •/•*,,-declare' • a--character-.with the'initial/value' v @'. *"/••

In this fragment of code the operation i n t z3 = 4 2 ; As you can see, the instruction MOVE D O , R is located
reserves a 16-bit memory location for the variable called z3 on line 12 and is stored in memory location 100C16.
and then stores the binary equivalent of 42, 0 in that location. This instruction is translated into the machine code
Whenever you use the variable z3 in the program, the com- 33C000002004,6, where the operation code is 33C016 and the
piler will automatically select its appropriate address in address of operand R is 00002004J6.
memory. All this is invisible to the programmer. The follow- The symbol table below the program relates symbolic
ing demonstrates the relationship between 68K assembler names to their value. This information is useful when you are
directives and the C code. debugging a program; for example, you can see that variable
P has the address 2000.
The assembler maintains a variable called the location
68K assembler directive C code equivalent counter, which keeps track of where the next instruction or data
element is to be located in memory. When you write an ORG
Time ' DS.W' - 1 i n t .'.time; ,;. directive, you preset the value of the location counter to that
x-- •' •DS.W '1 ' :, 'iht : ' .x/...y; . specified; for example, ORG $ 12 3 4 means load the following
Y- -DS.W• " -1 ' -
DC', W - -42 instruction or data into memory at location 1234I6. Let's look as
2 3 . •'•• • ' • • • i ' r i t ••;.'•' • z ' 3 : - . = 4 2 ; •/••••'
:
Term' : DC. B "v.cha'r' • ; t e r m . = ; ... , @'; some of the other assembler directives in this program.
6.1 Structure of a 68K assembly language program 231

00000000 1
00000000 2 * Program Number OUP1
00000000 3 * Written by A. C l e m e n t s
00000000 4 * Date C r e a t e d 10 O c t o b e r 2003
00000000 5 * Description Use of a s s e m b l e r directives
00000000 6 5
00000000
7
00001000 8 ORG $io"o~cT~——•
00001000 9
00001000 3039 00002000 The line number
10 MOVE P,D0
00001006 D079 00002002 11 ADD Q,D0
0000100C 33C0 00002004 12 MOVE D0,R
00001012 4E72 2700 13 STOP #$2700 The source code
00001016 14
00002000 15 ORG $2000
00002000 01 16 P DC.W 2
000H2Ii02 02 17 DC.W 4
Q
^ 0 0 02o'o4^L. 18 R DS .W 1
OCTo"TT2TT06 ^ S . 19 END $1000

No errors detected
No warnings generate^

The code and data


SYMBOL TABLE INFORMATION

Symbol-name Value
P 2000
Q 2002
Address in memory
R 2004

The symbol table relates symbolic


names to their addresses

Figure 6.3 Assembling a program.

bits) and the 68K's memory is byte addressed. Each word


The define constant assembler directive DC loads a constant
occupies two bytes—P takes up 2000i6 and 2001lf).
in memory before the program is executed; that is, it provides a
means of presetting memory locations with data before a The define storage directive (DS) tells the assembler to
reserve memory space and also takes a . B, . w, or . h qualifier.
program runs. This directive is written DC. B to store a byte,
DC. W to store a word, and DC. L to store a longword. In the For example, R DC. w 1 tells the assembler to reserve a word
program of Fig. 6.3, the assembler directive P DC. W 2 placesin memory and to equate the name of the word with 'R'. The
the value 2 in memory and labels this location 'P'. Because difference between DC. B N and DS. B N is that the former
this directive is located immediately after the ORG $2000 stores the 8-bit value N in memory, whereas the latter reserves
assembler directive, the integer 2 is located at memory loca-N bytes of memory by advancing the location counter by N.
tion 200016. This memory location (i.e. 200016) can be The final assembler directive, END $ 10 0 0, tells the assem-
referred to as P. When you wish to read the value of P (i.e. the
bler that the end of the program has been reached and that
contents of memory location 200016), you use P as a source there's nothing else left to assemble. The parameter taken by
operand; for example, MOVE P , D 0 . Because the size of the the END directive is the address of the first instruction of the
operand is a word, the value 00000000000000102 is stored in program to be executed. In this case, execution begins with
location 200016. Figure 6.4 demonstrates the effect of this the instruction at address 100016.
assembler directive. The assembler directive EQU equates a symbolic name to a
The next assembler directive, Q DC. W 4, loads the con- numeric value. If you write Tuesday EQU 3, you can use the
stant 4 in the next available location—200216. Why 2002i6 symbolic name 'Tuesday' instead of its actual value, 3. For
and not 200116? Because the operands are word sized (i.e. 16 example, ADD #Tuesday,DO is identical to ADD #3,DO.
232 Chapter 6 Assembly language programming

We now provide another example of the use of assembler EASy68K simulator, which allows you to cross-assemble a 68K
directives. program on a PC and then execute it on a PC. The PC simu-
lates the behavior of a 68K processor and the basic operating
Half the fun in writing assembly language programs is run-
system function required to perform simple input and output
ning and debugging them. In this chapter we will be using the
activities such as reading from the
keyboard and writing to the screen.
Memory Memory Memory
Figure 6.5 gives a screen dump of a
2000 2000 $0002 2000 $0002 session with the simulator.
2002 2002

2004 2004 6.1.2 Usingthe


cross-assembler
(a) ORG $ 2 0 0 0 sets (b)P DC.W 2 (c) Location $2000
the location counter puts $0002 in the has the symbolic
value P. Using
The following 68K assembly language
to 2000. current location
and moves the 'P' in the program program illustrates what an assembler
location counter to is the same as using
$2000.
does. This program is designed only to
the next free location.
demonstrate the use of assembler direc-
Figure 6.4 The effect of a define constant assembly directive. tives; it does not perform any useful

v^mt^mtmmmimmmmssmKm
0e B^f tit™ 2ptK»ss l&fc
BioTtal -.-I- 'lal <B|
Registers'
O»-|O00O0005 M-J00OO000O »B-|O0000S02 •"•"(OOOOOOOO" T S IHT XTOUC Cycles..
126
M-fo3o5Ho7r os-foooooobV «i-[oo5S55o" «s«|SBHo5oo" ^ " f 5 " 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
B2=[0O0Q0000 B4«|o0000000 <t2-|00000000 «6-|O0000000 l*C»p[)00040E QesjCyc&ss

ra«[oooooooo D7-|oooooooo *3»joooooooo OT-joooooooo~ ss-joioooooo


00000400 Start 3ng Address
Assembler used EA5y68K Editor vl 9 2 A
treated On 10-Oct-03 9 54 37 PM

00000000 1
oooooooo 2 * Program Number
00000000 3 * Written by
oooooooo 4 * Date Created
oooooooo 5 * Description
oooooooo 6
oooooooo
*
00000400 8 ORG S000400 Define the origin for data
00000400 41FA 00FE 9 TEA BUFFER (PC) A0 Preset A0 as a pointer register
00000404 6100 0022 10 KEXTIH BSR GET CHAR Get a character
00000408 10C1 11 HOVE B D1.(A0)+ Store character and move pointer to next
0000040A B23C 0040 12 CMP B #'9\D1 IF character = '#' THEN print

00000410 41FA 00EE 14 PRINT LEA BUFFER(PC) A0 Reset pointer to start of buffer
00000414 1218 15 KEXTOUT MOVE B (A0J+.D1 Get a character and update pointer
00000416 B23C 0040 16 CMP B *'»'.D1 IF character - '9' THEN EXIT
0000041A 6700 0008 17 BEQ DONE
0000041E 6100 0010 18 BSR PUT CHAR ELSE print character
00000422 60F0 19 BRA MEXTOUT Repeat
00000424 4E72 2700 20 DONE STOP #62700 Halt the 68K
00000428 21
00000428 103C 0005 22
*
GET CHAR MOVE B #5, DO Input routine
0000042C 4E4F 23 TRAP *15 Load input command in DO and call O/S
0000042E 4E75 24 RTS Return
00000430 25
00000430 103C 0006 26
*
POT CHAK MOVE B #6. DO Output routine
00000434 4E4F 27 TRAP #15 Load output command in DO and call O/S
00000436 4E75 28 RTS Return
00000438 29
00000500 30
* ORG S500
00000500 31 BUFFER DS.B 40 Reserve 40 bytes of storage
00000528 32 END S400

lio errors detected


Ho earnings generated

SYMBOL TABLE INFORMATION

Symbol-name Value
BUFFER 500
DOME 424
GET CHAR 428
<l I
J
2i.

Figure 6.5 Output from the Easy68K simulator.


6.1 Structure of a 68K assembly language program 233

computation. The source program is followed by its assem-


bled listing file. Examine both the source code and listing file,
and try to follow what is happening.

ORG $400
Test EQU 6 Dummy equates
Alan EQU 7
XXX DS.W 2 Save two words of storage
YYY DC.L $12345678 Put the longword $12345678 in memory
Name DC.B 'Clements' Put an ASCII string in memory
DC.B $FF
DC.L Test+Name Store a 32-bit constant
DC.B 4 Put 4 in memory
Begin MOVE.L #Name,A0 Start of code
Next MOVE.B (A0)+,D0 Pick up a character
CMP.B #$FF,D0 Test for end of string
BEQ Exit And exit on terminator
BSR Print Print a character
BRA Next Repeat
Exit STOP #$2700 Halt the 68K
*
Print NOP Dummy subroutine
NOP
RTS Return
*
END Begin END needed ("Begin" is start of code)
The following listingfilewas produced by a cross-assembler
from the above source code.
1 00000400 ORG $400
2 00000006 TEST: EQU 6 ;Dummy equates
3 00000007 ALAN: EQU 7
4 00000400 00000004 XXX: DS.W 2 ;Save two words of storage
5 00000404 12345678 YYY: DC.L $12345678 ;Put the longword $12345678 in memory
6 00000408 436C656D656E NAME: DC.B 'Clements' ;Put an ASCII string in memory
7473
7 00000410 FF DC.B $FF
8 00000412 0000040E DC.L TEST+NAME /Store a 32-bit constant
9 00000416 04 DC.B 4 ;Put 4 in memory
10 00000418 207C00000408 BEGIN: MOVE.L #NAME,A0
11 0000041E 1018 NEXT: MOVE.B (A0)+,D0 ;Pick up a character
12 00000420 0C0000FF CMP.B #$FF,D0 /Test for end of string
13 00000424 67000008 BEQ EXIT /And exit on terminator
14 00000428 61000008 BSR PRINT /Print a character
15 0000042C 60F0 BRA NEXT /Repeat
16 0000042E 4E722700 EXIT: STOP #$2700 /Halt the 68K
17 *
18 00000432 4E71 PRINT: NOP /Dummy subroutine
19 00000434 4E71 NOP
20 00000436 4E75 RTS /Return
21
22 00000418 END BEGIN /END needed ("Begin" is start of code)

Lines: 22, Errors: 0, Warnings: 0.

The first column provides the line number. The second used as a label and refers to the location in memory of the
column defines the location in memory into which data and code on this line. This address is $0408. Therefore, the
instructions go. The third column contains the instructions constant to be stored is 6 + $0408 = $040E. You can see that
and the constants generated by the assembler. The remainder this really is the value stored from column 3 in line 8. Note
is the original assembly language program. Consider line 8. that line 10 has the location $0418 and not $0417 because all

8 00000412 0000040E DC.L TEST+NAME /Store a 32-bit constant

The constant stored in memory is TEST+NAME. In line 2


TEST was equated to 6 (i.e. the assembler automatically sub- word and longword addresses must be even. The following
stitutes 6 for TEST). But what is 'NAME'? On line 6, NAME is notes will help you understand the assembly process.
234 Chapter 6 Assembly language programming

The simulator system requires an ORG statement at the Because the END address assembler directive terminates
beginning of the program to define the point at which code is the assembly process, no instructions beyond END point are
loaded into the simulated memory. assembled.
You can halt a 68K by executing the STOP # d a t a instruc-
tion, which stops the 68K and loads the 16-bit value d a t a
into its status register. By convention we use the constant
$2700 (this puts the processor in the supervisor mode, turns 6.2 The 68K's registers
off interrupt requests, and clears the condition code flags).
Operations on address registers always yield longword results The 68K has a byte-addressable architecture. Successive bytes
because an address register holds a 32-bit pointer. A . W opera- are stored at consecutive byte addresses 0,1, 2, 3 . . . , succes-
tion is permitted on an address register but the result is treated sive words are stored at consecutive even addresses 0, 2, 4,
as a two's complement value and sign-extended to 32 bits. 6 , . . . , and successive 32-bit longwords are stored at addresses

BEGINNER'S ERRORS
1. Embedded data 3. Subroutine call
You should not locate data in the middle of a section of code. You call a subroutine with a BSR or a JSR instruction. This is
The microprocessor executes instructions sequentially and will the only way you call a subroutine. You cannot call a
regard embedded data as instructions. Put data between the subroutine with a conditional branch (e.g. BEQ, BNE, BCC,
end of the executable instructions of a program and the END etc.).
assembler directive as the following demonstrates.

MOVE. B D3 , D4 The last instruction


STOP #$2700 This stops the 68K dead in its tracks
Datal DC.B 'This is data'
Test DS.B 4 Save 4 bytes of storage
END $400 The END directive is that last item in a program

The only way that you can locate data in the middle of a pro-
gram is by jumping past it like this:

MOVE.B D3 , D4 An instruction
BRA Continue Jump past the data
Datal DC. B 'This is data' Put the string here
Test DS.B 4 Save 4 bytes of storage
Continue ADD.B #1,D6 Back to the instructions

Although this code is legal, it is not good practice (for the 4. Misplaced E N D directives
beginner) to mix code and data.
The END directive indicates the end of the program. No
instruction or assembler directive may be placed after the END
2. Initialization
directive. The END must be followed by the address of the first
I saw a program beginning with the operation instruction to be executed.
MOVE . B (A0) , DO which loads DO with the byte pointed at
by address register AO. It failed because the student had not
defined an initial value of AO. You have to set up AO before you
can use it or any other variable by, for example.

LEA Table, A0 A0 points to "Table"

MOVE.B (A0),D0 Pick up a byte from Table

Table DC.B 1,2,3,7,2 Here's the table


6.2 The 68K's registers 235

8 bits 16 bits 32 bits

*~ ( I ~1 " | I

1000 1000 1000 ! 1001 1000 1000 ! 1001 j 1002 1003

1001 1002 1002 | 1003 1004 1004 ! 1005 I 1006 1007

1002 1004 1008


1003 1006 100C
1004 1008 1010
1005 100A 1014
1006 100C 1018
1007 100E 101C
1008 1010 1020
1009 1012 1024

—Vi____L
T
Byte-wide Word-wide
memory
^ —
Longword-wide Figure 6.6 The 68K's m e m o r y
memory memory space.

0 , 4 , 8 , . . . . Figure 6.6 illustrates how the 68K's memory space of their registers. In such cases, learning assembly language is
is organized. rather like learning to conjugate irregular foreign verbs.
Figure 6.6 poses an interesting question. If you store a The 68K's data registers are written DO to D7. To refer to
32-bit longword at, say, memory location $1000, where do the sequence of consecutive bits i to j in register DM we write
the 4 bytes go? For example, if the longword is $12345678, Dni:j. For example, we indicate bits 8 to 31, inclusive, of D4 by
does byte $12 go into address $1000 or does byte $78 go into D4 (831) . This notation is an extension of RTL and is not part
address $1000? of the 68K's assembly language.
The 68K stores the most-significant byte of an operand at When a byte operation is applied to the contents of a data
the lowest address (in this case $12 is stored at $1000). This register, only bits d00 to d07 of the register are affected.
storage order is called Big Endian (because the 'big end' of a Similarly, a word operation affects bits d^ to d,5 of the regis-
number goes in first). The term Big Endian has been bor- ter. Only the lower-order byte (word) of a register is affected
rowed from Gulliver's Travels. Intel processors are Little by a byte (word) operation. For example, applying a byte
Endian and store bytes in the reverse order to the 68K operation to data register D1 affects only bits 0 to 7 and leaves
family. bits 8 to 31 unchanged, CLR . B Dl forces the contents of D1
The 68K stores the most-significant byte of a word in bits to XXXXXXXXXXXXXXXXXXXXXXXX00000000, where
d08 to d15 at an even address and the least-significant byte in the Xs represent the old bits of Dl before the CLR . B Dl was
bits d00 to d07 at an odd address. Executing MOVE.W executed. If [Dl] = $12345678 before the CLR. B Dl, then
DO, 1234, stores bits d00 to d07 of DO at byte address 1235 [Dl] = $12345600 after it.
and bits dos to d15 of DO at byte address 1234. To avoid con- Further examples should clarify the action of byte, word,
fusion between registers and bits, we use 'D' to indicate a reg- and longword operations. In each case we give the 68K form
ister and 'd' to indicate a bit. We introduced the 68K's of the instruction and its definition in RTL. We use slice nota-
registers in the previous chapter; now we examine some tion to indicate a range of bits.
of their features. In Fig. 6.6 we've labeled the individual bytes
Assembly from RTL definition
of the 16-bit and 32-bit memory space in blue to demon-
strate that the most-significant byte of a word or longword is ADD.L D0,D1 [01(0:31)1 *- [ D l ( 0 31,1 + [D1,C;3„]
at the low address. ADD.W D0,D1 [ D l ( C ! l 6 ) ] <- [ D l , „ H l l + [00,0:16,]
ADD.B D0,D1 [Dl r J :7>] <" [Dl,,, Vl + [DO,;,:-,]

If the initial contents of DO and Dl are $12345678 and


6.2.1 Data registers $ABCDEF98, respectively, the ADD operation has the follow-
The 68K has eight general-purpose data registers, numbered ing effects on the contents of D1 and the carry bit, C.
DO to D7. Any operation that can be applied to data register Di
can also be applied to D;. No special-purpose data registers ADD.L D0,D1 results in [Dl] = BK0246I 0 and [C] = 0
are reserved for certain types of instruction. Some micro- ADD. 5-; D0,D1 results in [Dl] = ABCD4510 and [C] = 1
processors do not permit all instructions to be applied to each ADD . 2 DO, D l results in [ D l ] = A B C D E F 1 0 and [C] = 1
236 Chapter 6 Assembly language programming

The state of the carry bit and other bits of the CCR are you use an address register to calculate the location of the
determined only by the result of operations on bits 0-7 for a next number in the series.
byte operation, by the result of operations on bits 0—15 for a Because the contents of an address register are considered
word operation, and by the result of operations on bits 0-31 to be a pointer to an item in memory, the concept of separate
for a longword operation. independent fields within an address register is quite mean-
One of the most common errors made by 68K program- ingless. All operations on address registers yield longword
values. You can apply a . L operation to an address register
mers is using inconsistent size operations on a data register, as
the following example demonstrates. but not a . B operation. No instruction may operate on the
low-order byte of an address register. However, word opera-
tions are permitted on the contents of
MOVE.B XYZ,D0 Get the 8-bit contents of memory location XYZ address registers because the 16-bit result
SUB.B #5,DO and subtract 5 to get [XYZ] - 5 of a . w operation is automatically sign-
CMP.W #12,DO Is ([XYZ] - 5) > 12
BGT Test extended to 32 bits. For example, the oper-
ation MOVEA.W #$8022,A3 has the
effect:
This example implements the operation IF ([ XYZ ] -5) >
12 THEN But note that the operand XYZ is created as a
byte value and yet it is compared with a word value. This frag- [A3] $FFFF8022
ment of code might work correctly sometimes if the contents
of bits 8 to 15 of DO are zero. However, if these bits are not The 16-bit value $8022 is sign extended to $FFFF8022.
zero, this code will not operate correctly. Similarly, MOVEA .W #$7022, A3 has the effect:

[A3] $00007022

6.2.2 Address registers


The concept of a negative address may seem strange. If you
An address register holds the location of a variable. Registers think of a positive address as meaning forward and a negative
A0-A6 are identical in that whatever we can do to Ai, we can address as meaning backward, everything becomes clear.
also do to A;'. Address register A7 is also used as a stack Suppose address register Al contains the value 1280. If
pointer to keep track of subroutine return addresses. We address register A2 contains the value —40 (stored as the
describe the use of the stack point in detail later in this appropriate two's complement value), adding the contents of
chapter. Al to the contents of A2 by ADDA. L Al, A2 to create a com-
Address registers sometimes behave like data registers. For posite address results in the value 1240, which is 40 locations
example, we can move data to or from address registers and back from the address pointed at by A1.
we can add data to them. There are important differences We conclude with an example of the use of address
between address and data registers; operations on address registers. Address register A0 points to the beginning of a
registers don't affect the status of the condition code register. data structure made up of 50 items numbered from 0 to 49.
If you are in the process of adding up a series of numbers, you Each of these 50 items is composed of 12 bytes and data
shouldn't have to worry about modifying the CCR every time register DO contains the number of the item we wish

MNEMONICS FOR OPERATIONS O N ADDRESS REGISTERS


Although some of the operations that can be applied to the Some assemblers for the 68K permit only the use of the A D D
contents of data registers can also be applied to the contents mnemonic for both ADD . w A l , D l and for A D D . w D 1 , A 1 .
of address registers, the 68K's assembler employs special Other assemblers demand that the programmer write ADDA . w
mnemonics for operations that modify the contents of an D l , A l and will reject A D D . w D l , A l . The purpose of forcing
address register. The following examples illustrate some of programmers to write MOVEA, A D D A , and SUBA instead of
these mnemonics. In each case, the destination operand is an
MOVE , ADD , and SUB when specifying address registers as
address register destinations is to remind them that they are dealing with
addresses and that these addresses are
ADDA.L D1,A3 ADDA = add to address register treated differently to data values (e.g.
MOVEA.L D1,A2 MOVEA = move to an address regi s t e r because of sign extension). Practical applica-
SUBA.W D1,A3 SUBA = subtract from an addres s r e g i s t e r tions of the 68K's address registers are pro-
CMPA.L A2,A3 SUBA = compare with an address r e g i s t e r vided when we discuss addressing modes.
6.3 Features of the 68K's instruction set 237

AO

AO points t o t h e start 1 2 - b y t e data block


of t h e data structure ( I t e m 0)

O f f s e t 12 x /
A1

1 2 - b y t e data block
A1 points t o t h e start Data
( I t e m /)
of the /th e l e m e n t structure

DO
/
1 2 - b y t e data block
( I t e m 49) Figure 6.7 Using an
address register to access
a data element.

to access. Figure 6.7 illustrates this data structure. Suppose processing operations, you can perform any data manipula-
we need to put the address of this item in Al. In what tion you require. However, the 68K provides some special-
follows use the operation MULU #n, DO, which multiplies the purpose data movement instructions to generate more
16-bit low-order word in DO by n and puts the 32-bit product compact and efficient code. The following three instructions
in DO. provide enhanced data movement capabilities.
We need to find
where the required Name Assembly form RTL definition
item falls within Exchange EXG Di,Dj [Temp] «- [ D i ] , IDi] <r- [Dj} [Dj] <- [Temp]
the data structure. Swap SWAP Di [ D i ( 0 : 1 5 ) l <~ [ D i ( [Di, :31)3 * - [Di,
In order to do this Load effective address LEA P,Ai [ A i ] <- p
we multiply the
contents of DO by 12 (because each item takes up 12 bytes). The EXG instruction is intrinsically a longword opera-
Then we add this offset to the contents of AO and deposit the tion that exchanges the contents of two registers (see
result in Al. That is, Fig. 6.8(a)). EXG maybe used to transfer the contents of an

MOLD #12,DO Calculate the offset into the data structure


MOVEA.L A0,A1 Copy AO to Ai
ADDA.L D0,A1 Add the offset to Al

6.3 Features of the 68K's


instruction set
We've already described the 68K's basic operations. We now address register into a data register and vice versa. SWAP
introduce some of the 68K's other instructions and demon- exchanges the upper- and lower-order words of a given data
strate how they are used and what happens as they are exe- register. The LEA (load effective address) instruction gener-
cuted on a simulator. ates an address and puts it in an address register.
Let's write a program that executes some of these data
movement instructions and then use the simulator to observe
6.3.1 Data movement instructions what happens as we trace through it. This program is just a
The MOVE instruction is the most common data movement random selection of data movement instructions—it doesn't
instruction. Indeed, by using a MOVE in conjunction with data actually do anything.
238 Chapter 6 Assembly language programming

Before Before

A2 D4

D3

After SWAP D4
AfterEXG A2,D3

A2

D3

Figure 6.8 The EXG and SWAP


(a) Effect of an exchange operation. (b) Effect of a swap operation.
instructions.

ORG $400
MOVE.L #$1234567 ,D0 Copy a 32-bit literal to a register
MOVE.B D0,D1 Copy a byte from a register to a register
MOVE.W D0,D2 Copy a word from a register to a register
MOVE.L D0,D3 Copy a longword from a register to a register
EXG D0,AO Exchange the 32-bit contents of two registers
SWAP D3 Swap the upper and lower words of a register
MOVEA.L Data,Al Copy contents of memory location into an address register
LEA Data,Al Copy the address "Data" into an address register
STOP #$2700
Data DC.L $ABCDDCBA Store a longword constant in memory at address "Data"
END $400

This source file produces the following listing file when


assembled.

1 00000400 ORG $400


2 00000400 203C12345678 MOVE.L #$12345678,DO
3 00000406 1200 MOVE.B D0,D1
4 00000408 3400 MOVE.W D0,D2
5 0000040A 2600 MOVE.L D0,D3
6 0000040C C188 EXG D0,A0
7 0000040E 4843 SWAP D3
8 00000410 227900000420 MOVEA.L DATA,A1
9 00000416 43F900000420 LEA DATA,A1
10 0000041C 4E722700 STOP #$2700
11 00000420 ABCDDCBA DATA DC.L $ABCDDCBA
12 00000400 END $400

We are going to use the simulator to run this program and supervisor stack pointer is selected (we will discuss the differ-
observe the contents of the simulated 68K's registers as the ence between these later). Throughout this chapter, all refer-
instructions are executed one by one. Figure 6.9 displays the ences to the stack pointer refer to the supervisor stack pointer,
contents of the simulated computer's registers immediately
after the program is loaded.2 Note that the 68K has two A7 2
This is the output from the Teesside simulator, which is a text-based
address registers labeled SS and US in all simulator output.
simulator unlike EASy68K which is Windows based. This text uses both
SS is the supervisor state stack pointer A7 and US is the user simulators. EASy68K is better for running programs in a debug mode, the
state stack pointer A7. When the 68K is first powered up, the Teesside simulator is better for creating files that can be used in a book.
6.3 Features of the 68K's instruction set 239

The DF command is entered by the user. The simulator displays the current
What follows is the simulator's respor" contents of the program counter (PC), the
status register (SR), the supervisor stack
pointer (SS), and the user stack pointer (US)

£>C^)00400 (SR=2000 (SSJ=OOAOOOOO*(US>00000000 X=0


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0
' A 4 = 0 0 0 0 0 0 0 0 A5=00000000 A6=00000000 A7=00A00000 Z=0
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V=0:
D4 = 00000000_D5=00000000 D6=0000O_Q00 D7=00000000 C=0 !
>JlOVE.L #31234 5 6 7 8 , DO)

These are the current


The simulator prints the contents of flag bits of the condition
data registers DO to D7 and address code register (i.e. The
registers AO to A7 lower byte of the SR)

This is the next instruction The simulator displays all


Figure 6.9 Structure of the output from
to be executed values in hexadecimal form
the simulator.

SP (i.e. A7). In Fig. 6.9, PC defines the current value of the pro-
gram counter, SR the status register containing the 68K's CCR,
and X, N, Z, V, and C are the CCR's flag bits.
The last line of the block of data in Fig. 6.9 is the
m n e m o n i c of the next instruction to be executed. Because the
simulator doesn't use symbolic names, all addresses, data val-
ues, and labels are printed as hexadecimal values. In Fig. 6.9,
the program counter is pointing at location 400 16 and the
instruction at this address is MOVE . L # $ 1 2 3 4 5 6 7 8 , D O .
We now execute this program, instruction by instruction.
The purpose of this exercise is to demonstrate the use of the
simulator and to show how each instruction affects the 68K's
internal registers as it is executed. To help you appreciate what
is happening, registers that have changed are depicted in blue.

PC=000406 SR=2000 SS=0OA0O000 US=00000000 X=0


A 0 = 0 0 0 0 0 0 0 0 A 1 = 0 0 0 0 0 0 0 0 A2=00000000 A3=00000000 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=O0AO0000 Z=0
D 0 = 1 2 3 4 5 6 7 8 D1=00000000 D2=00000000 D3=00000000 V=0
D 4 = 0 0 0 0 0 0 0 0 D 5 = 0 0 0 0 0 0 0 0 D6=00000000 D7=00000000 C=0
>MOVE.B D0,D1

The first instruction, MOVE.L # $ 1 2 3 4 5 6 7 8 , D O , has been


executed. T h e only registers that have changed are DO and the
program counter. The PC has increased by 6 because the
instruction had a 2-byte op-code and a 4-byte immediate
value. T h e shortest 68K instruction is 2 bytes and the longest
is 10 bytes. T h e next instruction to be executed, M O V E . B
DO , D l , copies the low-order byte of DO to D 1 .

PC=000408 SR=2000 SS=0OAO0000 US=00000000 X=0


A 0 = 0 0 0 0 0 0 0 0 A 1 = 0 0 0 0 0 0 0 0 A2=00000000 A3=00000000 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A6=00000000 A7=00A00OOO Z=0
D 0 = 1 2 3 4 5 6 7 8 D l = 0 0 0 0 0 0 7 8 D2=00000000 D3=00000000 V=0
D 4 = 0 0 0 0 0 0 0 0 D5=00000000 D6=00000000 D7=00000000 C=0
>MOVE.W D0,D2
240 Chapter 6 Assembly language programming

As you can see, only the least-significant byte of DO has


been copied to D l . The next two instructions, MOVE.W
DO, D2 and MOVE . L DO , D 3 , demonstrate the transfer of a
word and a longword, respectively.

PC=00040A SR=2000 SS=00A00000 US=00000000 X=0


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=00A00000 Z=0
D0=12345678 Dl=00000078 D2-C0005678 D3=00000000 V=0
D 4 = 0 0 0 0 0 0 0 0 D 5 = 0 0 0 0 0 0 0 0 D6=00000000 D 7 = 0 0 0 0 0 0 0 0 C=0
>MOVE.L D0,D3

FC=00040C SR=2000 SS=00A00000 U S = 0 0 0 0 0 0 0 0 X=0


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=OOAOOOO0 Z=0
D0=12345678 Dl=00000078 D2=00005678 D3-12345678 V=0
D 4 = 0 0 0 0 0 0 0 0 D 5 = 0 0 0 0 0 0 0 0 D 6 = 0 0 0 0 0 0 0 0 D7=0000000O C=0
>EXG D0,A0

The next instruction, EXG DO, AO, exchanges the contents of


a pair of registers to give

P O 0 0 0 4 0 E SR=2000 SS=00A00000 U S = 0 0 0 0 0 0 0 0 X=0


A0=12345678 A1=00000000 A2=00000000 A3=00000000 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=00A0OOOO Z=0
DO-00000000 Dl=00000078 D2=00005678 D3=12345678 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>SWAP D3

The SWAP instruction swaps the upper and lower order


words of a data register.

PC=000410 SR=2000 SS=O0A00OOO U S = 0 0 0 0 0 0 0 0 X=0


A0=12345678 A1=00000000 A2=00000000 A3=00000000 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=OOAO00OO Z=0
D0=00000000 Dl=00000078 D2=00005678 D3-56781234 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>MOVEA.L $ 0 4 2 0 , A l

TheMOVEA.L D a t a , A l and L E A D a t a , A l instructions


have the following effects.

PC=000416 SR=2000 SS=OOA00OOO U S = 0 0 0 0 0 0 0 0 X=0


A 0 = 1 2 3 4 5 6 7 8 A1=ABCDDCBA A 2 = 0 0 0 0 0 0 0 0 A 3 = 0 0 0 0 0 0 0 0 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=OOA000OO Z=0
D0=00000000 Dl=00000078 D2=00005678 D3=56781234 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>LEA.L $0420,Al

PC=00041C SR=2000 SS=O0AO0000 U S = 0 0 0 0 0 0 0 0 X=0


A0=12345678 Al=00000420 A2=00000000 A3=00000000 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=00A0OO00 Z=0
D0=00000000 Dl=00000078 D2=00005678 03=56781234 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>STOP #$2700
6.3 Features of the 68K's instruction set 241

A MOVEA. L D a t a , A l instruction loads address register Al


with the contents of the operand Data, whereas LEA D a t a ,
A l loads A l with the address of the operand (the significance
of this will become clear later). We now look at instructions
that do more than move data from one place to another.

6.3.2 Using arithmetic operations


We've already encountered arithmetic instructions. N o w we
demonstrate their use by writing a program to calculate
Z = (X 2 + Y 2 )/(X - Y) where X and Y are 16-bit unsigned
integers. The 68K provides 16-bit x 16-bit multiplication
with a 32-bit product. The following program uses unsigned
multiplication and division (MULU and Divu). We will
assume that X and Y are positive values and that X > Y.
LIU. X a i t IJK.

ORG $400 Start of t h e program

M O V E . V. X,D0 Fut the value of X in DO


MtfUJ DO, DO Calculate X' (16-bit o p e r a n d s , 32-bit result)
MOVE.W Y,D1 Put the value of Y in Dl
MULU D1,D1 Calculate Y'
ADD. h D0,D1 Add >1 to Y and put the 3 2 - b i t r e s u l t i n Dl
HOVE.K X,D2 Put t h e value of X in 02
SUb.W Y,D2 Subtract Y from D2 t o g e t D2 = X - i
DiVU D2,D1 Divide Dl by D2 t o get (X:' -t T')/(X - Y)3
MOVE.W m,z Put t h e r e s u l t now in Dl i n t o Z
STOP #$2700

ORG $500 Put the data here

DC.W 50 I n i t i a l dummy value for v a r i a b l e X


DC.W 12 I n i t i a l dummy value for v a r i a b l e ' Y
':%•'•• DS.W 1 Reserve space for t h e r e s u l t

END $400 End of program and address of e n t r y poirit

Remember that you can't perform a memory-to-memory


subtraction—you have to load one of the operands onto a
data register. We assemble this program to create a listing file.

1 00000400 ORG $400 ;Start of the program


2
3 00000400 303900000500 MOVE.W X,DO ;Put the value of X in DO
4 OO0Q040S COCO MUUJ DO,, DO ; Calculate X z , ' •
5 00000408 323900000502 MOVE.W Y,D1 ;Put the value o f Y in Dl
6 0000040E C2C1 MULU , DI,DJ /Calculate1 ,Y2 '.'''.'' :
' ,'•'
7 00000410 D280 ADD.L D0,D1 ;Add X1' to Y 2 and put result in Dl
8 00000412 343900000500 MOVE.W X,D2 ;Put the value Of ,X in,D2 ' ,' ,'
9 00000418 947900000502 SOB.'w Y,D2 /Subtract Y from D2 to get x - Y ,
4 S
10 0000041E 82C2 DIVD D2,D1 ,-Diylde DltoyD2 to'get (X + Y )/(X - Y) '
11 00000420 33C100000504 MOVE.W D1,Z ?Put the result now in Dl into Z
12 00000426 .4E722700 STOP . #$2700 ' • : ' . • • •

14 00000500 , ORG
ORG $500
$500 ;Put
;Put the data here
the data •
here •
15
16 00000500 0032 ' X; DC.W 50 -•
50 ; I n i t i a l dummy
;Initial dummy value
value for for X X -
- , •.•
,
17 00000502 O00C Y; DC.W 12
12 • ,;initial
• - i n i t i a l dummy
dummy vvalue
a l u e lloro r yY
18 .00000504 00000002 Z; , DS.W 1
1 - /.•Reserve'space
,'.* Reserve' space for, £ or, the
t h e result
r e s u l t ,,"
" -, •
,.-..•.p.. ,, ,,,, . •'
13
20 000Q0400 „ ESD • $400
$4,00 ';tend,of program and
;fend,of program address-of entry
and address-of entry, pqi»t'<
p a i n t , .. .- v

3
The DIVU D2, D l instruction divides the 32-bit value in D l by the
16-bit value in D2. The 16-bit quotient is placed in the low-order word of
D1 and the 16-bit remainder is placed in the upper-order word of D1.
242 Chapter 6 Assembly language programming

We can use the simulator to run this program line by line


and observe its execution. If we examine memory initially,
we get.

000500 00 32 00 0C 00 00 00 00 00 00 00 00 00 00 00 00

The first six digits 000500 give the first memory location
on the line, and the following 16 pairs of digits give the con-
tents of 16 consecutive bytes starting at the first location.
Location 50015 contains 3216 = 50, and location 50216 con-
tains 0C16 = 12. These values were set up by the two DC. W
(define constant) assembler directives.
The state of the system prior to the execution of the first
instruction is

PC=000400 SR=2000 SS=00A00000 US=00000000 • X=0


A0=00000000 Al=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=00A00000 Z=0
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>MOVE.W $0500,DO

We are going to step through this program a line at a time


and display the contents of the registers as we execute each
instruction. Values that change are displayed in blue to make
the program easier to follow.

PC=000406 SR=2000 SS=00A00000 US=00000000 X=0


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=0OAOO0OO Z=0
D0=00000032 D1=00000000 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>MULU.W DO,DO

The instruction MOVE.w $0500, DO has been executed


and the contents of memory location 50016 have been copied
into data register DO.

PC=000408 SR=2000 SS=00A00000 US=00000000 X=0


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=OOA0OOOO Z=0
DO=000009C4 Dl=00000000 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>MOVE.W $0502,Dl

W e have just executed M U L U DO , DO and the contents of DO


is 9C416. This is 50 X 50 = 2500 = 9C4,6.

PC=00040E SR=2000 SS=00A00000 US=00000000 X=0


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=00A00000 Z»0
DO=000009C4 Dl=0000000c D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>MULU.W D1,D1
6.3 Features of the 68K's instruction set 243

PC=000410 SR=2000 SS=O0A0OOO0 US=OO0000OO X=0


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=O0A00OO0 Z=0
DO=000009C4 Dl=00000090 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>ADD.L DO,Dl

At this stage D l contains C 16 2 = 12 X 12 = 144 = 90 l 6 .

PC=000412 SR=2000 SS=OOAOO00O US=00000000 X=0


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=0OAOO00O Z=0
DO=000009C4 Dl=OO0O0A54 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>MOVE.W $0500,D2

We have now calculated X 2 + Y2 and deposited the result


in data register D l .

PC=000418 SR=2000 SS=00A00000 US=00000000 X=0


A 0 = 0 0 0 0 0 0 0 0 A 1 = 0 0 0 0 0 0 0 0 A2=00000000 A3=00000000 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=0OA0OOOO Z=0
DO=000009C4 D1=00000A54 D2=00000032 D3=00000000 V=0
D 4 = 0 0 0 0 0 0 0 0 D5=00000000 D6=00000000 D7=00000000 C=0
>SUB.W $0502,D2

PC=00041E SR=2000 SS=OOAOO0OO US=00000000 X=0


A 0 = 0 0 0 0 0 0 0 0 A 1 = 0 0 0 0 0 0 0 0 A2=00000000 A3=00000000 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=00A00000 Z=0
D0=000009C4 D1=00000A54 D2=00000026 D3=00000000 V=0
D 4 = 0 0 0 0 0 0 0 0 D5=00000000 D6=00000000 D7=00000000 C=0
>DIVU.W D2,D1

PC=OO0420 SR=2000 SS=00A00000 US=00000000 X=0


A 0 = 0 0 0 0 0 0 0 0 A 1 = 0 0 0 0 0 0 0 0 A2=00000000 A3=00000000 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A6=00000000 A7=OOA0OOO0 Z=0
D0=000009C4 D l = 0 0 1 6 0 0 4 5 D2=00000026 D3=00000000 V=0
D 4 = 0 0 0 0 0 0 0 0 D5=00000000 D6=00000000 D7=00000000 C=0
>MOVE.W Dl,$0504

The 68K instruction D I V U D2 , D l divides the 32-bit con-


tents of data register D l by the lower-order 16 bits in data
register D2. The result is a 16-bit quotient in the lower-order
word of D l and a 16-bit remainder in the upper-order word
of D l . That is, A54 1 6 /9C4 1 6 = 45 1 6 remainder 1616. The con-
tents of D l are $00160045.

PC=000426 SR=2000 SS=O0A0OOOO US=00000000 X=0


A 0 = 0 0 0 0 0 0 0 0 A 1 = 0 0 0 0 0 0 0 0 A2=00000000 A 3 = 0 0 0 0 0 0 0 0 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=OOA0OO0O Z=0
D0=000009C4 D l = 0 0 1 6 0 0 4 5 D2=00000026 D3=00000000 V=0
D 4 = 0 0 0 0 0 0 0 0 D 5 = 0 0 0 0 0 0 0 0 D6=00000000 D7=00000000 C=0
>STOP #$2700
244 Chapter 6 Assembly language programming

The MOVE, w Dl, $ 0 5 0 4 stores the low-order 16-bit result logical operation AND. B # % 0 0 0 0 0111, DO to get OOOOOyyy
in Dl in memory location 504If) (i.e. Z). We've used a in DO.
wordlength operation and have discarded the remainder in By using the NOT, AND, OR, and EOR instructions, you can
the upper-order word of D1. Now we look at the contents of perform any logical operations on a word. Suppose you wish
memory location 500 onward. to clear bits 0,1, and 2, set bits 3,4, and 5, and toggle bits 6 and
7 of the byte in DO. You could write
000500 00 32 00 0C 00 45 00 00 00 00 00 00 00 00 00 00.
AND.B #%11111000,DO C l e a r b i t s 0, 1, and 2
As you can see, memory location 50416 now contains the OR.B #%00111000,DO S e t b i t s 3 , 4, and 5
EOR.B #%11000000,DO T o g g l e b i t s 6 and 7 .
integer result of (502 + 122)(50 - 12) = 45, 6 = 69.
If [DO] initially contains 01010101, its final contents will
be 10111000. We will look at a more practical application of
6.3.3 Using shift and logical operations bit manipulation after we have covered branch operations in
We now demonstrate the use of shift and logical operations. a little more detail.
Logical shifts enable you to extract specific bits in a word.
Consider an 8-bit byte in DO with the format xxyyyzzz, where 6.3.4 Using conditional branches
the xs, ys, and zs are three groups of bits that have been You can't write programs without using the conditional
packed into a byte. Suppose we wish to extract the three ys branches required to implement loops and other control
from this byte.
constructs. We now look at the branch again and demonstrate

LSR.B #3,DO Shift DO right 3 places to get OOOxxyyy in DO


AND.B #%0000011l,D0 Clear bits 3 to 7 of DO to get OOOOOyyy

The first instruction LSR. B #3 , DO shifts xxyyyzzz right its use. Consider the following example of an addition fol-
to get OOOxxyyy in DO. We remove the xs by means of the lowed by a branch on negative (minus).

SHIFT OPERATIONS— A REMINDER


The assembly language forms of the 68K's shift instructions are

LSL #n,D0 shi ft c o n t e n t s o f DO n p l a c e s left logically


LSR #n,D0 s h Lft c o n t e n t s o f DO n p l a c e s right logically
ASL #n,D0 sh-Lft c o n t e n t s o f DO n p l a c e s left arithmetically
ASR #n,D0 s h Lft c o n t e n t s o f DO n p l a c e s right arithmetically

The integer n indicates the number of places to be shifted.


These instructions can be applied to bytes, words, and long-
words. If you shift a word by more than one place, the end
value of the carry bit is determined by the final shift. Consider
the following examples:

Initial contents of DO Operation Final contents of DO


11001100 LSL.B #1,D0 10011000
11001100 LSR.B #1,D0 01100110

11001100 ASL.B #1,D0 10011000


11001100 ASR.B #1,D0 11100110

1010111100001100 ASR.W #3,DO 1111010111100001


0011100001111101 ASR.W #4,DO 0000001110000111

11001110 ROL.B #1,D0 10011101


11001110 ROR.B #l,DO 01100111
11110000 ROL.B #2,DO 11000011
6.3 Features of the 68K's instruction set 245

SUB D1,D2 Subtract Dl from D2 and branch IF the result in negative


BMI ERROR

ELSE p a r t Beware
Here be bugs
THIS C O D E IS W R O N G ! ! !
ERROR THEN p a r t

The operation SUB Dl, D2 subtracts the contents of Dl EXIT and skips past the ' ERROR ' clause. Figure 6.10 demon-
from D2, deposits the results in D2, and updates the condi- strates the flow of control for this program.
tion code register accordingly. Remember we said earlier that not all the 68K's instruc-
When the BMI instruction is executed, the branch is taken tions affect die CCR. For example, consider the following two
(the THEN part) if the N-bit of the CCR is set because the examples.
addition gave a negative result. The
branch target is the line labeled by ERROR ADD D 1 , D 2 Add the contents of Dl to the contents of D2
and the intervening code between BMI
BMI ERROR If the result is negative, branch to ERROR
ERROR and ERROR . . . is not executed. and
If the branch is not taken because the ADD D 1 , D 2 Add t h e c o n t e n t s of Dl t o t h e c o n t e n t s of D2
result of SUB Dl, D2 was positive, the EXG D 3 , A4 Exchange t h e c o n t e n t s of D3 and A4
code immediately following the BMI EXG D 5 , A 6 Exchange the c o n t e n t s of D5 and A6
ERROR is executed. This code corresponds BMI ERROR If t h e r e s u l t of t h e a d d i t i o n was n e g a t i v e ,
to the ELSE part of the I F THEN ELSE
b r a n c h t o ERROR
construction. Both these fragments of code have the same effect as far as
Unfortunately, there's an error in this example. Suppose the BMI ERROR is concerned. However, the second case might
that the subtraction yields a positive result and the ELSE part prove confusing to the reader of the program who may well
is executed. Once the ELSE code has been executed, we fall imagine that the state of the CCR prior to the BMI ERROR is
through to the THEN part and execute that too, which is not determined by the EXG D3 , DA instruction.
what we want to do. After the ELSE part has been executed, it's
necessary to skip round the THEN part by means of an BRA Example 1 Suppose you want to write a subroutine to con-
instruction. The unconditional branch instruction, BRA vert a 4-bit hexadecimal value into its ASCII equivalent.
EXIT forces the computer to execute the next instruction at
ASCII character He)
Hexadecimal value Binary value

SUB D1,D2 0 30 0000


BMI ERROR 1 31 0001
) ELSE part
2 32 0010
)
BRA EXIT Skip past the THEN part 3 33 0011
ERROR ) 4 34 0100
) THEN part 35 0101
5
) 6 36 0110
EXIT
7 37 0111
Start 8 38 1000
39 1001
1 9
1010
A 41
true / x^ false B 42 1011
C 43 1100
[ . X ^S^/' •
D 44 1101
THEN, ELSE E 45 1110
F 46 1111

T Table 6.1 Relationship between ISO/ASCII characters and hexa-


Figure 6.10 Flow of control for an IF ... THEN ... ELSE construct. decimal values.
246 Chapter 6 Assembly language programming

Table 6.1 illustrates the relationship between the binary The CMP s o u r c e , d e s t i n a t i o n subtracts the source
value of a number (expressed in hexadecimal form) and its operand from the destination operand and sets the flag bits of
ASCII equivalent (also expressed in hexadecimal form). For the CCR accordingly; that is, a CMP is the same as a SUB except
example, if the internal binary value in a register is that the result is not recorded.
00001010, its hexadecimal equivalent is A16. In order to
print the letter 'A' on a terminal, you have to transmit the
Example 2 Consider the following algorithm.
ASCII code for the letter 'A' (i.e. $41) to it. Once again,
please note that there is a difference
between the internal binary repre-
* IF x = y THEN y = 6
sentation of a number within a com- * IF x < y THEN y = y + 1
puter and the code used represent the *
symbol for that number. The number CMP.B D1,D0 Assume that x is in DO and y in :Dl
six is expressed in 8 bits by the binary BNE NotEqu IF x = y THEN
MOVE.B #6,D1 y = 6
pattern 00000110 and is stored in the BRA exit and leave the algorithm
computer's memory in this form. On NotEqu BGE exit IF x < y THEN exit
the other hand, the symbol for a six ADD.B #1,D1 ELSE y = y + 1
(i.e. '6') is represented by the binary exit exit point for the algorithm
pattern 00110110 in the ASCII code.
If we want a printer to make a mark on paper corresponding
to '6', we must send the binary number 00110110 to We perform two tests after the comparison CMP .B DO, D l .
it. Consequently, numbers held in the computer must One is a BNE and the other a BGE. We can carry out the two
be converted to their ASCII forms before they can be tests in succession because there isn't an intervening instruc-
printed. tion that modifies the state of the CCR.
From Table 6.1 we can derive an algorithm to convert a Although conditional tests performed by high-level
4-bit internal value into its ASCII form. A hexadecimal value languages can be complex (e.g. IF x + Y - z > 3t), the condi-
in the range 0 to 9 is converted into ASCII form by adding tional test at the assembly language level is rather more basic
hexadecimal 30 to the number. A hexadecimal value in the as this example demonstrates.
range $A to $F is converted to ASCII by adding hexadecimal
$37. If we represent the number to be converted by HEX and
the number to be converted by ASCII, we can write down a Templates for control structures
suitable algorithm in the form We now represent some of the control structures of
high-level languages as templates in assembly language. A
IF HEX < 9 THEN ASCII HEX 30 1 6 template is a pattern or example that can be modified to suit
ELSE ASCII HEX 37 1 6 the actual circumstances. In each of the following examples,
the high-level construct is provided as a comment to the
assembly language template by means of asterisks in the
We can rewrite the algorithm as
first column. The condition tested is [DO] = [Dl] and the
actions to be carried out are A c t i o n l or A c t i o n 2 . The
ASCII = HEX + $30 templates can be used by providing the appropriate test
IF ASCII > $39 THEN ASCII ASCII + 7 instead of CMP D0,D1 and providing the appropriate
sequence of assembly language statements instead of
This algorithm can be translated into low-level language as A c t i o n l or A c t i o n 2 .

Note: D0.B holds HEX value on subroutine entry


D0.B holds the ASCII character code on return
No other register is modified by this subroutine
ADD.B #$30,DO ASCII = HEX + $30
CMP.B #$39,DO IF ASCII < $39 THEN EXIT
BLE EXIT
ADD.B #7, DO ELSE ASCII = ASCII + 7
EXIT RTS
6.3 Features of the 68K's instruction set 247

IF [DO] = [Dl] THEN Actionl

CMP D0.D1 Perform test


BNE EXIT IF [DO] * [Dl] THEN exit
Actionl ELSE execute Actionl

EXIT Exit point for construct

IF [DO] = [Dl] THEN Actionl ELSE Action2

CMP D0,D1 Compare DO with Dl


BNE Action2 IF [DO] * [Dl] perform Action2
Actionl Fall through to actionl if [DO] = [Dl]

BRA EXIT Skip round Action2


Action2 Action2

EXIT Exit point for construct

FOR K = I TO J

ENDFOR

MOVE #1,D2 Load loop counter, D2. with I


Actionl Perform Actionl

ADD #1, D2 Increment loop counter


CMP #J+1,D2 Test for end of loop
BNE Actionl IF not end THEN go round again
EXIT ELSE exit

* WHILE [DO] = [Dl] Perform Actionl

Repeat CMP DO, Dl Perform test


BNE EXIT IF [DO] * [Dl] THEN exit
Actionl ELSE carry out Actionl

BRA Repeat REPEAT 'loop


EXIT Exit from construct

REPEAT Actionl UNTIL [DO] = [Dl]

Actionl Perform Actionl

CMP D0,D1 Carry out test


BNE Actionl REPEAT as long as [DO] * [Dl]
EXIT Exit from loop

CASE OF I
1 = 0 ActionO
1 = 1 Actionl
1 = 2 Action2
1 = 3 Action3

I = N ActionN
I > N Exception
CMP.B #N,I Test for I out of range
BGT EXCEPTION IF I > N THEN exception
MOVE.W I, DO Pick up value of I in DO
MULU #4,DO Each address is a longword
LEA Table,A0 A0 points to table of addresses
LEA (A0,D0), AO A0 now points to case I in table
MOVEA.L (A0),A0 A0 contains address of case I handler
JMP (A0) Execute case I handler
248 Chapter 6 Assembly language programming

Table ORG <address> Here is the table of exceptions


ActionO DC.L <addressO> Address of case 0 handler
Actionl DC.L <addressl> Address of case 1 handler
Action2 DC.L <address2) Address of case 2 handler

ActionN DC.L <addressN> Address of case N handler

EXCEPTION ... Exception handler here

The case number I stored in DO must be multiplied by 4 « Sbjts „


before it can be added to the address in AO. This action is
necessary because the cases numbers are consecutive integers Memory
0,1,2,3 while the addresses of the case handlers are consecu-
tive longword addresses (i.e.AO + 0,A0 + 4,A0 + 8,. . . ) . INPUT ±_o_^__^_j_j^_y_^_
OUTPUT _A__B_^_D_J_J__G__H_
Putting it all together
Consider a system with eight single-bit inputs (P, Q, R, S, T, U,
V, W) and eight single-bit outputs (A, B, C, D, E, F, G, H). We're
not interested in the details of input/output techniques here
and assume that reading a memory location whose address is
INPUT loads the values of P to W into a data register. Similarly, Figure 6.11 The memory map of two input/output ports.
writing the contents of a data register to memory location
OUTPUT sets up the eight output bits A to H. The formats of
the input and output control words are defined in Fig. 6.11. Let's look again at the compare instruction, CMP, that com-
Suppose that a system has to implement the following pares two operands and sets the bits of the CCR accordingly.
control operation. CMP.B #%0001000,DO compares the contents of DO with
the value 000100002 by evaluating [DO] - 00010000. The
IF ( (P = 1) AND (Q = 0) )OR ( (P = 0) AND (S 1>)
THEN C = 1; E = 0 result is discarded, leaving the contents of DO unaffected by
ELSE C = 0; E = 1 flie CMP operation. Only the bits of the CCR are modified. If
ENDIF DO contains 00010000, the subtraction yields zero, setting
We have to translate this algorithm into 68K code. the Z (zero) flag of the CCR. The following operation,
The above action involves the testing of three bits of INPUT BEQ TRUE, results in a branch to the instruction whose address
(P, Q, and S), and then setting or clearing two bits of is labeled TRUE. Comparison instructions are of the form
OUTPUT (C and E). The bits of OUTPUT not involved in CMP s o u r c e , d e s t i n a t i o n . The difference between CMP
the algorithm must not be affected in any way by operations Di, D j and SUB Di, D j is that the former evaluates Di — D;
on bits C and E.
MOVE.B INPUT,DO Get input status
AND.B #%11000000 DO Mask out all bits but P and Q
CMP.B #%10000000 DO Test for P = 1, Q = 0
BEQ TRUE Goto action on test true
MOVE.B INPUT,DO Get input status again
AND.B #%10010000 DO Mask out all bits but P and S
CMP.B #%00010000 DO Test for P = 0, S = 1
BEQ TRUE Goto action on test true
FALSE MOVE.B OUTPUT,DO Get the output control word
AND.B #%11011111 DO Clear bit C
OR.B #%00001000 DO Set bit E
MOVE.B DO,OUTPUT Set up new output control word
BRA EXIT Branch past actions on test true
TRUE MOVE.B OUTPUT,DO Get the output control word
AND.B #%11110111 DO Clear bit E
OR.B #%00100000 DO Set bit C
MOVE.B DO,OUTPUT Set up new output control word
EXIT Continue
6.4 Addressing modes 249

POINTS TO REMEMBER

The assembly language symbol % indicates that the following operand, but the actual operand itself, A N D . B
number is interpreted as a binary value and the symbol $ #%11000000, DO means calculate the logical AND
means that the following number is interpreted as a between the binary value 11000000 and the contents of DO.
hexadecimal value, A N D . B #%11000000, DO tells you much If we had made a mistake in the program and had written
more than the hexadecimal and decimal forms of the operand, A N D . B %11000000,DO (ratherthan A N D . B
AND.B #$C0,D0andAND.B #192,DO, respectively. #%11000000,DO),the instruction would have AN Ded DO
The symbol # informs the assembler that the following with the contents of memory location %11000000
value is not the address of a memory location containing the (i.e. location 192).

and throws away the result, whereas the latter evaluates guage programming and introduce a wealth of variations on
Di — Dj and puts the result in Dj. address register indirect, addressing.
The label FALSE is a dummy label and is not in any way
used by the assembly program. It merely serves as a reminder
to the programmer of the action to be taken as a result of the 6.4.1 Immediate addressing
test being false. At the end of this sequence is an instruction
BRA EXIT. A BRA (branch) is equivalent to a GOTO in a high- Application o f i m m e d i a t e addressing
level language and causes a branch round the action taken if As an arithmetic constant
the result of the test is true.
MOVE NUM,D0 [DO] <- [NUM
ADD #22,DO [DO] <- [DO] + 22
6.4 Addressing modes MOVE D0,NTJM [NUM] <- [DO]

Addressing modes include all the ways of specifying the loca- This sequence of instructions is equivalent to the high-level
tion of an operand used by an instruction. We encountered language construct NUM = NUM + 22 and increases the value
the fundamental addressing modes, absolute, immediate, and in memory location NUM by 22. That is, [NUM] <- [NUM] +
address register indirect, in the previous chapter. Now we 22. The 68K can, in fact, add an immediate operand to a
demonstrate how some of these are used in assembly lan- memory location directly without using a data register by

REVIEW OF IMMEDIATE ADDRESSING


Immediate addressing allows the programmer to specify a number is binary.The instructions MOVE #25, DO,
constant as an operand. The value following the op-code in an MOVE #$19, DO, and MOVE #%00011001, DO have identical
instruction is not a reference to the address of an operand but effects.
is the actual operand itself. The symbol # precedes the Immediate addressing is used when the value of the
operand to indicate immediate addressing.The four instructions operand required by an instruction is known at the time the
below demonstrate how absolute and immediate addressing program is written; that is, it is used to handle constants as
modes are represented in assembly language and in RTL opposed to variables. Immediate addressing is faster than
absolute addressing, because only one memory
Assembly language form RTL form Name

MOVE 1234,DO [DO] <- [1234] absolute addressing


MOVE #1234,DO [DO] <-1234 immediate addressing
ADD 1234,DO [DO] < - [ D 0 ] + [ l 2 3 4 ] absolute addressing
ADD #1234,DO [DO] <- [D0] + 1234 immediate addressing

The symbol # is not part of the instruction. It is a message to reference is required to read the instruction during the fetch
the assembler telling it to select that code for MOVE that uses phase. When the instruction MOVE # 5 , DO is read from
the immediate addressing mode. Don't confuse the symbol # memory in a fetch cycle, the operand, 5, is available
with the symbols $ or %.The $ indicates only that the following immediately without a further memory access to
number is hexadecimal and the % indicates that the following location 5, to read the actual operand.
250 Chapter 6 Assembly language programming

SPECIAL 68K IMMEDIATE OPERATIONS

The 68K provides three instructions with immediate source called data-to-memory and are indicated by appending an I
operands, which allow you to perform an operation directly on to the instruction mnemonic. The three instructions with this
the contents of a memory location. These operations can be facility are A D D I , S U B I , and C M P I . Consider

CMPI.B #42,$1234 Compare the contents of location $1234 with 42


SUB.W #$F23D,(AO) Subtract F23D16 from the contents of the
memory location pointed at by AO

means of the special add immediate instruction ADDI. For such as N+1, the assembler evaluates it and replaces it by the
example, ADDI #22 , NUM adds the constant value 22 to the calculated value—in this example #N+1 is replaced by 11. We
contents of the location called NUM. use the comparison with N + 1, because the counter is
incremented before it is tested. On the last time round the
In a comparison with a constant
loop, the variable I becomes N + 1 after incrementing and the
Consider the test on a variable, NUM, to determine whether it
branch to NEXT is not taken, allowing the loop to be
lies in the range 7 < NUM < 25.
exited. This loop construct can be written in a more elegant
fashion, but at this point we're interested only in the applica-
MOVE NUM,DO Get NUM in DO
CMP #8,DO Compare it with 8 tion of immediate addressing as a means of setting up
BMI FALSE IF negative NUM < 7 counters.
CMP #25,DO Compare it with 25
BPL FALSE IF positive NUM > 24
TRUE 6.4.2 Address register indirect
addressing
FALSE In address register indirect addressing, the operand is
specified indirectly via the contents of a pointer register. RISC
As a method of terminating loop structures. processors allow any register to act as a pointer, whereas the
A typical loop structure in both Java and C is illustrated 68K reserves address registers for this function. The box
below. provides a review of this addressing mode.

for ( i = 0 ; i < N+l; i++)


Using address register indirect addressing
to access a table
Figure 6.12 demonstrates how you'd add up a sequence
of numbers using ADD. B (AO), DO . The computer reads
The high-level language FOR construct may readily be trans- the contents of address register AO (i.e. 1000l6) and then reads
lated into 68K assembly language. In the following example, the contents of memory location 100016 (i.e. 25). This
the loop counter is stored in data register DO. operand is then added to die contents of DO.

EQU 10 Define the loop size - we've used N = 10 here

MOVE #1,D0 Load DO with initial value of the loop counter


NEXT Start of loop

Body of loop

ADD #1,D0 Increment t h e l o o p c o u n t e r


CMP #N+1,D0 T e s t f o r t h e end of t h e l o o p
BNE NEXT IF n o t end THEN r e p e a t l o o p

At the end of the loop, the counter is incremented by We can add 100 numbers by means of address register indi-
ADD #1,D0. The counter, DO, is then compared with its rect addressing in the following way. This isn't efficient
terminal value by CMP #N+1,D0. If you write an expression code—we'll write a better version later.
6.4 Addressing modes 251

REVIEW OF ADDRESS REGISTER INDIRECT ADDRESSING


Register indirect addressing specifies the address of an Some texts call this addressing mode indexed addressing or
operand by the contents of an address register. The diagram modifier-based addressing.The manufacturers of the 68K
illustrates the effect of MOVE . B ( AO ) , DO when reserve the term indexed addressing to indicate a particular
[AO] = 100016.The computer first reads the contents of variant of address register indirect addressing in which the
address register AO and then reads the contents of memory effective address of an operand is calculated by adding the
pointed at by AO.The contents of AO are 1000, so the contents of two registers.
processor reads the contents of memory location 1000 to get
the actual operand, 25.

Address register
AO points to the location OFFE
of the operand OFFF
25 1000
100l\
AO 1002 \
1003 \ u
This is the
<004 location pointed
1005 atbyAO.
DO
25

The following instructions illustrate address register


indirect addressing and provide RTL definitions for the
action to be carried out, together with a plain language
description.

Assembly language RTL definition Description

MOVE (A0),D0 [DO] <- [[AO]] Move the contents of the memory pointed at by AO to DO

M0VED1,(A2) [[A2]] <r- [Dl] Move the contents of D1 to the location pointed at by A2

ADD (A1),D2 [D2] <- [D2] + [ [Al] Add the contents of the location pointed at by Al to the
contents of D2

MOVE ( A l ) , (A2) [[A2]] [[AH; Move the contents of the location pointed at by Al to the
location pointed at by A2

ORG $001000 Start of the program


CLR DO DO is the number counter
MOVEA #NUM1,A0 AO points to the first number
CLR Dl Clear the total in Dl
LOOP ADD (A0),D1 Add in the number pointed at by A0
ADDA #2,A0 Point to the next number in the list
ADD #1,D0 Increment the number counter
CMP #100,DO Have we added the 100 numbers?
BNE LOOP If not then repeat
STOP #$2700 Halt the program
ORG $2000 Data region
NtJMl DC.W 1,2,3,4,5 Dummy data (only 5 numbers given here)
END $1000

The pointer in address register A0 is incremented by 2 on each memory elements are words and each word occupies 2 bytes in
pass round the loop—the increment of 2 is required because the memory. We can express this program in a more compact way.
252 Chapter 6 Assembly language programming

r "~ ~* w 'i
OFFE AO
OFFF
1000 1000 p 01
OFFF
1001 Q 1
Address register AO points I • 25 1000
1002 R 2
at memory location 1000 1 -|QQ-|
1003
AO / 1002 1004 Offset with respect
1000 | 1 ^ / 1003 to AO

initial value of DO X 1004 ^-——-~__


DO / f U ^ _ J 1005
77* I / The effect of Figure 6.14 Using address register indirect addressing with
— 1 I ADD.B ( A 0 ) , D O displacement.
^ .r when AO contains 1000,
A37 I ^("\ DO contains 12 and
- ^ \ v7 memory location 1000 d l 6 (Ai), where d l 6 is a 16-bit constant and Ai an address
Final value of D 0 \ ^ J contains 25. register. The effective address of an operand is calculated by
adding the contents of the address register specified by
Figure 6.12 Using address register indirect addressing. the instruction to the signed two's complement constant that
forms part of the instruction. Figure 6.13 illustrates how the
effective address is calculated for the instruction
MOVE.B 4 (AO) ,D0. Some 68K simulators permit you to
OFFE
AO OFFF write either MOVE. B 4 (AO) , DO orMOVE.B (4,A0),D0.
1000 Offset We can define MOVE dl6(A0),DO in RTL as
1001 +0
1002 +1 [D0]<-[dl6 + [AO]], where d l 6 is a 16-bit two's comple-
Displacement = + 4
1003 +2 ment value in the range — 32K to 32K. This constant is called
DO 1004 +3
a displacement or offset because it indicates how far the
1 1 Jr 15 1005* +4
operand is located from the location pointed at by AO.
The displacement can be negative; for example;
MOVE . B -4 (AO), DO specifies an operand 4 bytes back from
The location accessed
is 4 bytes on f r o m that the location pointed at by AO.
ffect Of MOVE . B 4 (AC ) , D 0
pointed at by AO Why would you wish to use this addressing mode?
Consider the data structure of Fig. 6.14 where three variables
Figure 6.13 An illustration of address register indirect P, Q, and R, have consecutive locations on memory. If we load
addressing with displacement.
address register AO with the address of the first variable, P, we
can access each variable via the pointer
LEA NUM1,A0 AO points at the list of numbers" inAO.
CLR DO Clear the total
MOVE #99,Dl In this fragment of code we define
Set up the counter for 100 cycles
LOOP ADD (AO),D0 Add in a number the displacements P, Q, and R as 0, 1,
ADDA.L # 2 , A 0 Point to next number and 2, respectively.
DBRA Dl,LOOP Repeat until all numbers added

The 68K's decrement and branch instruc- p EQU 0


Q EQO 1
tion DBRA D l , LOOP implements a loop. This
R EQU 2
instruction subtracts 1 from the contents of Dl
and branches back to the line labeled by LOOP.
If, however, Dl is decremented and goes from 0
to — 1, the loop is not taken and the next instruc- LEA Block,A0 AO p o i n t s t o "Block"
MOVE B P(A0),D0 Evaluate R = P + Q
tion in sequence is executed. Because the branch ADD.B Q(A0),D0
terminates on — 1 rather than 0, loading D1 with MOVE B D0,R(A0)
N causes DBRA D l , LOOP to execute N + 1 times.
4
The LEA or load effective address instruction loads an address regis-
Address register indirect addressing with displacement ter with an address. The effect of LEA NUM1, A0 is to load A0 with the
A more general form of the 68K's address register indirect address NUM1 (and not the contents of NUM1). This instruction is
equivalent to MOVEA.L #NUM1,A0. The LEA instruction doesn't
addressing mode is called the address register indirect address- require a # symbol to indicate a literal operand because the source
ing mode with displacement. The effective address is written operand is always an address.
6.4 Addressing modes 253

This code adds two numbers and stores their sum in The instruction MULU <ea>,Di multiplies the 16-bit word
memory. But where in memory? The location of the three at the effective address specified by <ea> by the lower-order
numbers is Block + P, Block + Q, and Block + R, respec- word in D,. The 32-bit longword product is loaded into
tively. Because the value of Block can be changed by the pro- D,(0.31). MULU operates on unsigned values and uses two 16-bit
grammer, we can locate the variables P, Q, and R in any three source operands to yield a 32-bit destination operand. As the
consecutive locations anywhere in memory. Why would we 68K lacks a clear address register instruction, we have to use
want to do that? If we access variables by specifying their either MOVEA.L #0,AO or the faster SUBA.L A 0 , A 0 t o
location with respect to a pointer, we can move the program clear A0.
about in memory without having to recalculate all addresses. Note the instruction CMPA.L #2*N,A0 containing the
expression 2*N, which is automatically evaluated by the
Using address register indirect addressing with assembler. The assembler looks up the value of N (equated to
displacement $10) and multiples it by 2 to get $20. Consequently, the
assembler treats CMPA. L #2*N,A0 as CMPA.L #$2 0,AO.
Let's look at an example of this addressing mode that involves
vectors. A vector is composed of a sequence of components; Variations on a theme
for example, the vector X might be composed of four elements
The 68K supports two variations on address register indirect
X{> XT.* ^ 3 ' One of the most common of all mathematical
XQI X\t
addressing. One is called address register indirect addressing
calculations x3. One of the most common of all mathematical
with predecrementing and the other is called address register
calculations (because it crops up in many different areas—
indirect addressing with postincrementing. The former
particularly graphics) is the evaluation of the inner or scalar
addressing mode is written in assembly language as - (Ai)
product of two vectors. Suppose A and B are two n-compo-
and the latter (Ai) + . Both these addressing modes use
nent vectors; the inner product S, of A and B, is given by
address register indirect addressing to access an operand
S = ^arbi = a0-b0 + a r b , + ••• + a„_,-fr„_i exactly as we've described. However, the postincrementing
If A = (1, 3, 6) and B = (2, 3, 5), the inner product S is mode automatically increments the address register after it's
given b y l - 2 + 3-3 + 6-5 = 41. Consider the case in which been used, whereas the predecrementing mode automatically
the components of vectors A and B are 16-bit integers. decrements the address register before it's used. Figure 6.15
demonstrates the operation
N EQO $10 16 components (N = 16) ADD.B (A0)+,D0. This
ORG $001000 Origin o f p r o g r a m
instruction adds the contents of
CLR DO [DO] 0
the location pointed at by A0
SUBA.L A0,A0 [A0] 0
(i.e. P) to the contents of data
LOOP MOVE VEC1(A0) Dl [Dl] [[A0 + VECl]
[Dl] register DO. After A0 has been
MULU V E C 2 ( A 0 ) ,D l [Dl] * [[A0] + VEC2]
ADD [DO] [DO] + [Dl] used to access P, the value of A0
D1,D0
ADDA.L #2,A0 [A0] [A0] + 2 is incremented to point at the
CMPA.L #2*N,A0 [A0] - 2N <- note N words = 2N b y t e s next element, Q.
BNE LOOP IF Z = 0 THEN [PC] <r~ LOOP Address register indirect
MOVE [S] < - [DO] addressing is used to access
D0,S
*
tables. If we access an item by
ORG $002000 O r i g i n of d a t a
DS 1 R e s e r v e a w o r d for t h e p r o d u c t
MOVE.B (A0),D0, the next
s
DS $20 R e s e r v e 16 w o r d s for V e c t o r 1 item (i.e. byte) in the table can
VEC1
VEC2 DS $20 R e s e r v e 16 w o r d s for V e c t o r 2 be accessed by first updating
the address pointer, A0, by
Before After ADDA # 1 , A0 and then repeat-
Effect of MOVE . B (A0 ) + , DO
ing the MOVE.B (A0),DO.The
68K's automatic postincre-
AO N-1 AO N-1 menting mode increments an
K 9 N + 1 [—| pP N address register after it has been
N+, *—» Q N+1 used to access an operand. This
Q
tqr m | |DO addressing mode is indicated by
DO
(Ai) +. Consider the following
(a)'Initially, address register AO points (b) After accessing elementP, A0 is incremented
at element P in memory which is accessed to point at the next element, Q. examples of address register
and loaded into DO. indirect addressing with post
Figure 6.15 Address register indirect addressing w i t h postincrementing.
incrementing.
254 Chapter 6 Assembly language programming

LEGALAND ILLEGAL ADDRESSING MODES


Because of the real-world constraints imposed by the encoding don't support an offset in the calculation of an effective
of instructions and the design of the chips themselves, not all address; that is, only (Ai)+ and ~(Ai) are legal. To make this
possible variations on addressing modes are supported. Both clear, we present several 68K instructions—some of these
the predecrementing and postincrementing addressing modes represent legal and some represent illegal addressing modes.

ADD.W ( A 2 ) - D2 illegal—postdecrementing not allowed


MOVE.W DO,(12,A1)+ illegal—offset not allowed with postincrementing
MOVE.W ~ ( A 2 ) (A3) + legal
SUB.W D3,+(A4) illegal—preincrementing not allowed
CMP.W (A6) + D3 legal

Assembly language form RTL definition


ADD.B (A2)+,D2 [D2] <- [D2] + [[A2]]; [A2] «- [A2] + 1

MOVE.B DO, ( A l ) + [[Al]] < - [DO] ; [Al] <- - [ A l ] + 1

CLR.W (A0) + [[AO]] <- 0 ; [AO] < - [AO] + 2

MOVE.W ( A 2 ) + , (A3) + [[A3]] <- [[A2]];


[A2] <- [A2] + 2; [A3] <- [A3] + 2

CLR.L (A0) + [[AO] ] <- 0 ; [AO] i- [AO] + 4

The pointer register is automatically incremented by 1 for ( A 2 > +, D 5 . Postincrementing leaves A2 pointing to the new
byte operands, 2 for word operands, and 4 for longword ( 0 p item on the stack,
operands. Consider the following examples.

MOVE.B (A0)+,D5 <- [D5 (0:7) ] [[AO] ] ; [AO] <r- [AO] + 1


MOVE.L (A0)+,D5 i- [05,0:3!)] [ [AO] ) ; [AO] <- [AO] + 4 Examples of register indirect
addressing with postincrementing
The 68K provides a predecrementing address register Let's revisit the program to add together 100 numbers stored
indirect addressing mode with the assembly language form in consecutive locations.

LEA NUM1,A0 A0 points at list of numbers


CLR.W DO Clear the total
MOVE.W #99,Dl Set up the counter for 100 cycles
LOOP ADD.W (A0)+,D0 Add in a number and move the pointer to next
DBRA Dl,LOOP Repeat until all numbers added

The instruction ADD.W (A0)+, DO adds the number


- (Ai), where the contents of Ai are decremented before pointed at by A0 to the contents of DO and then moves the
they are used to access the operand at the address pointed at pointer to point to the next number in the sequence.
by Ai. As above, the predecrement is by 1,2, or 4, depending Let's look at another example of this postincrementing
on whether the operand is a byte, word, or longword, addressing mode. Suppose we have a table of N unsigned
respectively. integer bytes and wish to locate the value of the largest. The
Predecrementing and postincrementing are complemen- number of bytes is less than 256. A simple pseudocode algo-
tary operations because one undoes the other. Suppose we rithm to do this is
use MOVE D3,—(A2) to store the contents of D3 on a
stack in memory. MOVE D3,— (A2) decrements A2 largest = 0
and then copies D3 to the top of the stack pointed at by FOR i = 0 to N-l
A2. After this instruction has been executed, A2 is read number^
if (number! > largest) THEN largest = numbert
pointing to the top item on the stack. We can remove END FOR
D3 from the stack and put it in D5 by executing MOVE
6.4 Addressing modes 255

This pseudocode uses the notation number, to indicate the If we use MOVE.B (AO) +, DO, the contents of address
ith element in a sequence. We can express this in 68K assem- register AO incremented to 100116 after the character
bly language as located at 1000 has been accessed and we are ready to access

ORG $400
EQO 10 Assume a dummy value of N = 10 {numbe r of elements)
CLR.B DO Use DO as largest and set it to 0
MOVE.W #N-1,D1 Use Dl as a counter and preset it to N-l
LEA List,A0 Use A0 as a pointer to the list
Next MOVE.B <A0)+,D2 Read a number
CMP.B D0,D2 Is new number > largest?
BPL Last If it isn't, go and check for end of loop
MOVE B D2,D0 It is, record the new largest number
Last DBRA Dl,Next Repeat until count exhausted
STOP #52700
ORG $1000 Let's put some test values here
List DC.B 1,4,8,6,2, i,7,6,9,3
END $400

Addressing modes and strings the next character in the string. Consider the following
A string is a sequence of consecutive characters. We will example.
assume the characters are 8-bit ASCII-encoded values. It's Counting characters Suppose we want to count the
necessary to indicate a string's size in order to process it. You number of characters in the string pointed at by address
could store a string as n, char_l, c h a r _ 2 , . . . , char_n, where n register A0 and return the string length in D3. The string is
is the length of the string. For example, the ASCII-encoded terminated by the null character, which is included in the
string 'ABC might be stored in memory as the sequence $03, character count.
$41, $42, $43.
You can also use a special termi- MOVE.B #0,D3 Preset the character counter to 0
nator or marker to indicate the end Again MOVE.B (A0)+,DO G e t a character into DO
of a string. Of course, the termina- ADD.B #1,D3 Increment t h e character counter
CMP.B #0,DO Is the character a null?
tor must not occur naturally in the
BNE Again Repeat until zero found
string. If the terminator is the null
byte, the string 'ABC would be At the end of this code, address register A0 will be pointing
stored as the sequence $41, $42, $43, $00. Some strings use the at the next location immediately following the string. We can
terminator $0D because this is the ASCII code for a carriage rewrite this fragment of code.
return.
The address of a string in memory is usually of the first
character in the string. Figure 6.16 shows a 10-character
> T 1000
string located at location 100016 in memory and terminated
by a null byte (i.e. 0). h 1001
Most microprocessors don't permit direct operations on e 1002
strings (e.g. you can't compare two strings using a single Address register 1003
instruction). You have to process a string by using byte oper- AO 1000 s 1004
ations to access individual characters, one by one. The char-
Tt 1005
acters of a string can be accessed by means of address register
indirect addressing. In Fig. 6.16, address register A0 contains This string begins in memory r 1006
location 1000 and extends
the value 1000!6, which is the address or location of the first to location 100A. i 1007
character in the string. n
11 1008
The operation MOVE . B (A0), DO copies the byte pointed rt
ft 1009
£
f >i
at by the contents of address register A0 into data register DO.
nul.
mil. 100A
Applying this instruction to Fig. 6.16 would copy the charac-
ter 'T' into data register DO (the actual data loaded into DO is,
of course, the ASCII code for a letter T ) .
Figure 6.16 Example of a string.
256 Chapter 6 Assembly language programming

i 1000 • T 2000
!> 1001 h 2001
tf 1002 e 2002
Address register 1003 Address register 2003
AO 1000 * 1004 A1 2000 S 2004
t 1005 t 2005
.- 1006 r 2006
This string begins in memory This string begins in memory
location 1000 and extends ! 1007 location 2000 and extends i 2007
to location 100A. to location 200A.
It 1008 n 2008
>: 1009 g 2009
nil:. 100A null 200A
Figure 6.17 Comparing two
strings.

CLR.B D3 Preset the character counter to 0


Again MOVE.B (A0)+,D0 Get a character into DO
ADD.B #1,D3 Increment the character counter
TST.B DO Is the character a null?
BNE Again Repeat until zero found

The new instruction, TST, tests an operand by comparing Comparing strings Suppose we wish to test whether two
it with zero and setting the flag bits in the CCR accordingly. strings are identical. Figure 6.17 shows two strings in mem-
ory. One is located at 100016 and the other at 200016. In this
Counting A's Suppose we want to count the number of times
case both strings are identical.
'A' occurs in a string that starts at address Find_A.

LEA F i n d A,A0 A0 points at the start of the string


CLR B Dl Clear the A's counter
Next MOVE: . B (A0)+,DO REPEAT Get a character
CMP B #'A',D0 IF 'A'
BNE Test
ADD B #1,D1 THEN increment A's counter
BRA Next
Test TST B DO UNTIL terminator found
BNE Next

The instruction CMP. B # ' A ' , DO compares the contents In order to compare the strings we have to read a character
of DO (i.e. the last character read from the string) with the at a time from each string. If, at any point, the two characters
source operand, # ' A'. The # symbol means the actual value do not match, the strings are not identical. If we reach two
and the 'A' means the number whose value is the ASCII code null characters, the strings are the same. A0 points at one
for the letter A. If you omit the # symbol, the processor will string and Al points at the other. We will set D7 to a zero if the
read the contents of memory location 41 )6 (because strings are not the same, and one if they are the same.
'A' = 4116). Because the MOVE instruction sets the CCR, we
can test for the terminator as soon as we pick up a character,
as the following code demonstrates.

LEA F i n d A,A AO points at the start of the string


CLR.B Dl Clear the A's counter
Next MOVE.B <A0)+,DO REPEAT Get a character
BEQ Exit Exit on null character
CMP.B #'A',D0 IF 'A'
BNE Next
ADD.B #1,D1 THEN increment A's counter
BRA Next END REPEAT
Exit
6.4 Addressing modes 257

CLR.B D7 Assume the strings are not the same


Next MOVE.B (A0)+,DO Read a character from the first string
CMP.B (A1)+,D0 Compare it with a char from the second string
BNE NotSame IF not the same THEN exit
TST.B DO REPEAT unit terminator found
BNE Next
MOVE.B #1,D7 IF terminator found then strings are equal
NotSame

Removing spaces A common string manipulation problem is We read characters from the string and copy them to their
the removal of multiple spaces in text If you enter a command destination until a space is encountered. The first space encoun-
into a computer like delete X, Y, Z the various component parts tered is copied across. We continue to read characters from the
(i.e. fields) of the command are first analyzed. A command line source string but do not copy them across if they are further
processor might remove multiple spaces before processing the spaces. This algorithm requires some care. If we are searching
command. Figure 6.18 shows how we might go about dealing for multiple spaces, we will move one character beyond the
with this problem. On the left, the string has three spaces. On the space because of the autoincrementing addressing mode.
right, the same string has been rewritten with only one space. Therefore, we have to adjust the pointer before continuing.
Because the final string will be the same size or shorter than Figure 6.19 demonstrates the operation of this algorithm.
the original string, we can simply move up characters when we By the way, there is a flaw in this program. What happens if
find a multiple space. We can use two pointers, one to point at the end of the string is a space followed by a null? How can
the original string and one to point at the final string. you fix the problem?

LEA String,AO Set both pointers to the start of the string


LEA String,Al
Next MOVE.B (A0)+,DO Get a character from the source string
MOVE.B DO,(Al)+ Copy it to its destination
TST.B DO If it is a null, then exit
BEQ Exit
CMP.B #' ',DO Was the character a space?
BNE Next If not a space, continue copying across
Loop MOVE.B (A0)+,DO Get another character from the source string
CMP.B #' ',D0 Is this a space too?
BEQ Loop Continue until a non-space is found
LEA -1(AO),A0 Wind the source pointer back to the last char
BRA Next Go back to the string
Exit Exit point

T T
h h
e e
Address register Address register
AO A1 t
e
t s
The string contains three t
e
spaces between 'The' and
'test' s null
(b) Register A1 points
t to the destination string.
(a) Register AO points null We move only the first
to the source string. space in a group.

Figure 6.18 Removing spaces from a string.


258 Chapter 6 Assembly language programming

Source string Destination string AO

AOI X A1L X AO points to the head Data block 1


of a data structures

DO

Y DO selects a given Data block 2


data block in the structure.

X X Offset
The offset selects an Data block 3
AO A1
item within a data Mock.

D1
Y

Figure 6.20 Indexed addressing—executing


X X
MOVE.B O f f s e t ( A O , D O ) , D l .
A0[_ A1C
Y

plus the contents of D6 plus 28, that is, [28 + [A3] +


X X [D6]] <- 0. Note that modern 68K assemblers permit
A1[ you to write either TUESDAY (AO, DO) or (TUESDAY,
AO A0,D0).
Y Indexed addressing is a variation on address register indi-
rect addressing. Instead of using one pointer register, the
effective address is given by the sum of the contents of two
X X
registers and a displacement. The displacement in indexed
A1L addressing lies in the range—128 to+127, whereas the
displacement in address register indirect addressing is
AOf Y —32K to +32K. Indexed addressing can be used to access
two-dimensional tables in which the location of an element is
specified by its row and its column position.
X X
Figure 6.20 illustrates MOVE. B Of f s e t (AO, DO) ,Dl.You
Y can regard AO as pointing at the beginning of a data structure.
AI In this example, we've shown three blocks of data. By adding
Y the contents of DO to AO we can select a specific data block in
A0|_
the structure. In the example of Fig. 6.20, the contents of DO
would be 6 (if each data block occupied 3 bytes).
Figure 6.19 Deleting multiple spaces. By adding a constant to the effective address created by
adding the two registers, we can access a particular element of
one of the data blocks. In Fig. 6.20, the offset is 1.
Consider a data structure representing a diary tfiat consists
Indexed addressing of several weeks, each of which is divided into 7 days. An item
The 68K provides a variant on the address register indirect of data is accessed by locating the head of the data structure,
addressing mode called indexed addressing., which uses two counting off the appropriate number of weeks, and then
registers to calculate the effective address of an operand. The accessing the required day. If the location of the array in
assembly language form of the effective address is written memory is called DIARY and we wish to access the location
d8 (Ai, x j ) , where d8 is an 8-bit signed constant forming corresponding to Tuesday of week five, we need to access
part of the instruction, Ai is one of the eight address registers, location DIARY + (WEEK-1)*7 + Tuesday. If Tuesday = 2,
and Xi is either one of D0-D7 or A0-A7. The effective the location of the required element is DIARY + (5—1) *
address is calculated from the expression d8 + [Ai] + [Xi]; for 1 + 2 = DIARY + 30.
example, CLR 2 8 ( A 3 , D 6 ) clears the contents of the The data structure can be accessed using indexed address-
location whose effective address is given by the contents of A3 ing by loading A0 with DIARY and DO with the location of the
6.4 Addressing modes 259

d l 6 (PC), for example, the operation 'Load data register DO


PC
relative' is written
MOVE fcil&fPC) ,DO
MOVE dl6(PC),D0
PC
The operand is and is defined as [DO] <- [[PC] + d l 6 ] . Asbefore, dl6 is
e dl6
d16 bytes from
instruction. a 16-bit two's complement offset that is normally written in
symbolic form and whose value is calculated by the assem-
DO
bler. Figure 6.21 demonstrates the relationship between the
PC, the instruction, and the operand address. Figure 6.21 is
Address -'
[PC] + d16 slightly simplified because the 68K's program counter is
automatically incremented by 2 after the instruction fetch
Figure 6.21 Program counter relative addressing- -the effect of phase.
MOVE d l 6 ( P C ) ,D0. Relative addressing lets you write position-independent
code (PIC), which avoids absolute addresses. The machine
start of the desired week, and then using the desired day as a code version of a program written in PIC is independent of
constant as demonstrated in the following fragment of code. the physical location of the program in memory. You can

SUNDAY EQU 0
MONDAY EQU 1
TUESDAY EQU 2
WEDNESDAY EQU 3

LEA DIARY, AO AO points to head of structure


MOVE.L WEEK,DO DO contains week number
SUB.L #1,D0 Calculate (Week - 1)*7
MULU #7,DO DO now contains number of days
MOVE. I TUESDAY(AO,DO),D1 Access the required item

6.4.3 Relative addressing move (i.e. relocate) PIC programs in memory without mod-
ifying them, MOVE 3 6 ( PC ) , DO means load data register DO
Before we introduce this addressing mode, we'll pose a prob- with the contents of the memory location 36 locations on
lem. Consider the operation MOVE $ 12 3 4, DO, which spec- from this instruction. It doesn't matter where the operation
ifies the absolute address $1234 as a source operand location. MOVE 3 6 (PC), DO lies in memory, because the data associ-
If you were to take the program containing this instruction ated with it will always be stored in the 36th location follow-
and its data and locate it in a different region of memory, ing the instruction.
would it work? No. Why not? Because the data accessed by the Calculating the displacement required by an instruction
instruction is no longer in location $1234. The only way to using program counter relative addressing is difficult.
run this program is to change all operand addresses to their Fortunately, you never have to perform this calculation—the
new locations. Relative addressing provides a means of relo- assembler does it for you. Consider the following example.
cating programs without changing addresses.
Relative addressing is similar to address register indirect ORG $400
addressing because the effective address of an operand is MOVE.B Valuel,DO Put Valuel in DO
MOVE.B Valuel(PC),D1 Put Valuel in Dl
given by the contents of a register plus a displacement. STOP #$2700
However, relative addressing uses the program counter to cal- Valuel DC.B $23
culate the effective address rather than an address register; END $400
that is, the location of the operand is specified relative to the
current instruction. The syntax of a 68K relative address is Let's assemble this code and see what happens.

1 00000400 ORG $400


2 00000400 10390000040E MOVE.B Valuel,DO ; P u t V a l u e l i n DO
3 00000406 123A0006 MOVE.B Valuel(PC),D1 ; P u t V a l u e l i n Dl
4 0000040A 4E722700 STOP #$2700
5 0000040E 23 Valuel: DC.B $23
6 00000400 END $400
260 Chapter 6 Assembly language programming

The address of operand V a l u e l is $0000040E (as a 32-bit Relative branching


longword). The instruction on line 2, MOVE. B V a l u e l , DO,
We've already met the branch instructions (e.g. BEQ, BNE),
contains an opcode ($1039) and the absolute address of the which can force a branch to the target address. What we
operand ($0000040E). haven't said is that the target address is expressed relative to
Now look at the instruction on line 3, MOVE.B the current value of the program counter. Most microproces-
V a l u e l (PC) , D l . The opcode is $123A and the operand is sors have a relative branching mode in which the destination
the 16-bit value $0006. When the 68K reads an instruction, of a branch instruction is expressed with reference to the cur-
the program counter is automatically incremented by 2. Once rent address in the program counter. Figure 6.22 illustrates
MOVE. B V a l u e l (PC), Dl has been read from memory, the relative addressing by means of a memory map; Fig. 6.22(a)
program counter is incremented by 2 from $00000406 to illustrates the instruction BRA XYZ, Fig. 6.22(b) shows how
$00000408. If we add the offset $0006 to $00000408, we get the instruction is encoded, and Fig. 6.22(c) shows a jump
$0000040E, which is the address of the operand Va l u e 1. instruction that performs the same function with an absolute
You can use relative addressing for source operands, but address.
not for destination operands. You can specify where an Figure 6.22(a) illustrates BRA XYZ, where XYZ is the target
operand comes from but not where it is going to by means of address. The machine code form (Fig. 6.22(b)), shows that
relative addressing (this restriction is a 68K design decision the offset corresponding to XYZ is stored as 4 because the tar-
and not a fundamental limitation). The instructions MOVE get address is 4 bytes beyond the end of the branch instruc-
12(PC),D3 and ADD 8(PC),D2 are legal instructions, tion. Remember that the program counter is automatically
whereas MOVE D3,12(PC) and ADD D2,8(PC) are illegal. incremented by two after the BRA instruction is read during
We can write completely position-independent code for an instruction fetch. The programmer doesn't have to worry
the 68K by loading the address of the operand into an address about short and long branches, or about calculating the
register using position-independent code and then using branch offset. If you write BRA ABC, the assembler computes
address register indirect addressing to access operands in the offset as ABC — [PC] — 2. Figure 6.22(c) demonstrates
memory. We use the LEA (load effective address) instruction to the JMP XYZ instruction, which uses an absolute address; that
load an address into an address register. Note that the instruc- is, XYZ is stored as $1006.
tions MOVEA. L #Temp7 , AO and LEA Temp7, A0 are equiva- The offset used by a relative branch is an 8-bit signed two's
lent. Consider the following examples of this instruction. complement number in the range —128 to +127. As 2 is

Assembly language form RTL definition


LEA $1000,A0 [A0] <- 1 0 0 0 1 6
LEA (AD ,A0 [A0] <- [Al]
LEA 10(Al),A0 [AO] <- [ A l ] + 10
LEA 10(PC),A0 [A0] <- [PC] + 10 This lets us generate PIC

The following fragment of code demonstrates how the automatically added to the PC at the start of an instruction,
LEA instruction can be used to support position independ- relative branching is possible within the range - 1 2 6 to +129
entcode. bytes from the start of the current instruction (i.e. the

LEA Valuel(PC),A0 Calculate the relative address of


VALUE1 and store it in A0

MOVE D2, (A0) Store D2 at the address pointed at by A0

MOVE (A0),D3 Move the word pointed at by A0 to D3

Valuel DS Reserve one word of memory for data

When the instruction LEA V a l u e l (PC) , A0 is assembled, branch). The 68K also supports a long branch with a 16-bit
the assembler takes the value of V a l u e l and subtracts the offset that provides a range of —32K to +32K bytes.
current value of the program counter from it to evaluate the Figure 6.22 also illustrates the importance of relative
offset required by the instruction. branching in the production of position-independent code.
We now look at one of the most important applications of The program containing the instruction BRA XYZ can be
program counter relative addressing, relative branching. relocated merely by moving it in memory, whereas the
6.4 Addressing modes 261

BRA op-code
1000 60 1000 JMP XYXi XYZ is stored
BRA XYZ
as the absolute
1001 04 +J Offset in 1001 0000- 'value 00001006
+;>instructioi 1006
1002 1002
1003 +3 1003
Offset from
1004 +4 current 1004
1005 +5 instruction 1005
•XYZ 1006 Target Target *6 1006 Target XYZ
1007 Next instruction 1007
to be executed

(a) Assembly language form of (b) Machine code form of the (c) Equivalent form using
the branch instruction. A branch instruction. The stored offset the JMP instruction with
is made to the instruction at is 4 because the destination is an absolute address.
target address XYZ. 4 bytes from the end of the Figure 6.22 Absolute and
current instruction. relative branching.

program containing J M P XYZ must be modified if it is tion is $00 0410 and the address of the operation
relocated. MOVE (AO) + , (Al) + is $00 040C. We therefore have to
The following program moves a block of data from one branch four locations from the start of the BNE, or six loca-
region of memory to another and provides examples of both rel- tions from the end of the BNE. As the CPU always increments
ative branching and relative addressing. The first location of the the PC by 2 at the start of a branch, the stored offset is
block to be moved is FROM and the first location of its destination —6. In two's complement form this is $FA (the code is
is TO. The number of words to be moved is given by SI ZE. $66FA).

ORG $400 Start of program to move a data block


SIZE EQU 16 Let's use a 16-byte block
LEA FROM(PC) , A 0 AO points to the source of the sate
LEA TO(PC),A1 Al points to the destination
MOVE.B #SIZE,D0 DO is the loop counter
REPEAT MOVE.B (A0)+,(Al)+ REPEAT Move byte from source to destination
SUB . B #1,D0
BNE REPEAT UNTIL all bytes moved
STOP #$2700

ORG $001000
FROM DS.B 16 Locate source and destination blocks here
TO DS.B 16
END $400

In Fig. 6.23 the instruction BNE REPEAT causes a branch Note how we use relative addressing to load the address of
backwards to instruction MOVE (AO) + , (Al) + in the event the source and destination blocks into address registers A0
of the zero bit in the CCR not being set. From the memory and Al, respectively. This program can be assembled to give
map of Fig. 6.23, we see that the address of the branch opera- the following.

1 00000400 ORG $400 Start of program


2 00000010 SIZE: EQU 16 Let's use a 16-byte block
3 00000400 41FA0BFE LEA FROM(PC),A0 A0 points to the source
4 00000404 4 3FA0C0A LEA TO(PC),Al Al points to the destination
5 00000408 103C0010 MOVE.B #SIZE,D0 DO is the loop counter
6 0000040C 12D8 REPEAT: MOVE.B (A0)+, (Al) + REPEAT move byte from source to destination
7 0000040E 5300 SUB . B #1,D0
8 00000410 6 6FA BNE REPEAT ;UNTIL all bytes moved
9 00000412 4E722700 STOP #$2700
10 *
11 00001000 ORG $001000
12 00001000 0 0 0 0 0 0 1 0 FROM: DS.B 16 rLocate source and destination blocks here
13 00001010 00000010 TO: DS.B 16
14 00000400 END $400
262 Chapter 6 Assembly language programming

000400 41 FA LEA FROM(PC),AO The LEA instructions


load pointer registers
^^^-000402) ^JBFjJ) AO and A1 with the target
addresses.
/ ^ 000404 / 43FA LEA TO(PC),A1
00040$/ OCOA
V „ (T\ 4 JXXM0& 103C MOVE.B # S I Z E , D 0
/ 00040A 0010
/REPEAT 00040C 12D8 MOVE.B (A0)+,(Al) +
When LEA FROM ( PC S , AO
is executed, the PC contains / 00040E 5300 SUB.B #1,D0
00000402. The offset 'FROM'
is OBFE. These are added / 000410 66FA BNE REPEAT
to get 00000402+ 0BFE = 000412 4E72
00001000, which is loaded
STOP #$2700
into AO 000414 2700

- - ^ ^ i
^—•001000 K^FROM

•./•; AC

001010 *TO
^ \ A 1 ...'••'.

Figure 6.23 Moving a block of data in memory.

RELATIVE ADDRESSING—A SUMMARY


Relative addressing is used to specify the location of an irrespective of where the code is located. Relative addressing
operand with respect to the program counter. This addressing is also used with branch instructions because the target
mode means that code and its data can be moved in memory address is expressed as the number of bytes from the current
without having to recompute operand addresses because the instruction.
data is the same distance from the code it accesses

pushed on to the stack, and when an item is removed from the


6.5 The stack stack it is said to be pulled (or popped) off the stack.
Figure 6.24 presents a series of diagrams illustrating the
We now look at one of the most important data structures in operation of a stack as items A, B, C, D, and E, are added to it
computer science, the stack, and describe the facilities pro- and removed from it.
vided by the 68K to support the stack (we provided a basic Before we look at the stack's role in subroutines, we must
introduction in the previous chapter). A stack is a last- mention die stack-based architecture that has been imple-
in-first-out queue with a single end, where items are added or mented by some special-purpose computers and by some
removed. Unlike a conventional first-in-first-out queue experimental machines. Suppose a computer can transfer
(FIFO), the stack has only one end. The stack expands as data between memory and the stack and perform monadic
items are added to it and contracts as they are removed. Items operations on the top item of the stack, or dyadic operations
are removed from the stack in the reverse order to which they on the top two items of the stack. A dyadic operation (e.g. +,
are entered. The point at which items are added to, or *, AND, OR) removes the top two items on die stack and
removed from, the stack is called the top of stack (TOS). The pushes the result of the operation.
next position on the stack is referred to as next on stack Figure 6.25 shows how an ADD instruction is executed by a
(NOS). When an item is added to the stack it is said to be stack-based computer. Figure 6.25(a) demonstrates a system
6.5 The stack 263

stack C D.
B B C Current top of stack
A A A contains element D
B
(a) Stack empty, (b) Push A. (c) Push B. (d) Push C.
A

(a) Initial state of the stack with four items.

D E
New top of stack
C C C C
B B B B
A A A A C ' D —
H Adder
(e) Push D. (f) Pull D. (g) Push E. (h) Pull E. B
A

(b) First element pulled off the stack.


B
(stack empty)
A •A
p
(i) Pull C. (j) uH 1 (k) Pull A.
D
Figure 6.24 The stack. (Adder
B
A G
with four data elements on the stack. When the ADD is exe-
cuted, the element at the top of the stack is pulled (c) Second element pulled off the stack.
(Fig. 6.25(b)) and sent to the adder. The next element (i.e. C,
the old NOS) is now the new TOS. In Fig. 6.25(c) the element
at the top of stack is pulled and sent to the adder. Finally, the
'I 1
output of the adder, D + C, is pushed onto the stack to create
a new TOS.
C+D
B

_D__J—- r " Adder
i
Note how this ADD instruction doesn't have an operand A
c —*
unlike all the instructions we've described so far. A stack-
based computer has so-called addressless instructions (d) Result pushed on the stark
because they act on elements at the top of the stack. Figure 6.25 Executing an A D D operation on a stack machine.
The following example illustrates the evaluation of the
expression (A + B ) ( C - D ) on a hypothetical stack-based
computer. We assume that the instruction PUSH pushes the on the stack in the way we've just described (e.g. ADD , SUB,
contents of DO onto the stack, ADD , SUB, and MULU all act on MULU), special-purpose microprocessors have been designed
the top two items on the stack, and PULL places the top item to support stack-based languages. The 68K implements
on the stack in DO. instructions enabling it to access a stack, although it's not a
stack machine. Pure stack machines
1. MOVE A, DO Get A in DO do exist, although they have never
2. PUSH Push it on the stack
been developed to the same extent as
3. MOVE B, DO Get B in DO
4. PUSH Push it on the stack the two-address machines like the
5. ADD Pull the top two items off the stack, add them, and push the result 68K and Pentium.
6. MOVE C DO Get C in DO
7. PUSH Push it on the stack
8. MOVE D DO GetD 6.5.1 The 68K stack
9. PUSH Push it on the stack
10. SUB Pull the top two items off the stack, subtract them, and push the result A hardware stack can be implemented
11. MULU Pull the top two items off the stack, multiply them, and push the result as a modified shift register. When
12. PULL Pull the result off the stack and put it in DO such a stack is implemented in hard-
Figure 6.26 represents the state of the stack at various ware, the addition of a new item to the top of stack causes all
stages in the procedure. The number below each diagram other items on the stack to be pushed down. Similarly, when
corresponds to the line number in the program. Although the an item is removed from the stack, the NOS becomes TOS
68K and similar microprocessors do not permit operations and all items move up.
264 Chapter 6 Assembly language programming

D
B C C C--D

A A A+B A+3 A+B A+B (A + B){C-D)

Step 2 Step 4 StepS Step 7 Step 9 Step 10 Figure 6 . 2 6 Executing a


Step 11
Push A Push B Add Push C Push D Subtract Multiply program o n a stack machine.

Memory Memory Memory Memory

SP SP B SP SP r*
fSP-1] — •
im A (SP] | — ¥ A+B ISP—11 H A+B

Step 2 Step 4 Step 5 Step 7

Memory Memory Memory

r*- D

SP C SP ["*" C-D SP
Figure 6 . 2 7 Executing t h e
JSP-2) A+B JSP-1J -> A+B [SP] —» <A+B)x
fc+D) program of Fig. 6.26 on a
Step 9 Step 10 machine w i t h a stack pointer.
Step 11

T H E T W O 6 8 K STACK P O I N T E R S

The 68K has t w o A7 registers and, therefore, t w o system stack is protected f r o m errors caused by t h e less reliable user
pointers. O n e A 7 is t h e supervisor stack pointer and is programs. A stack pointer dedicated solely t o t h e operating
associated w i t h t h e operating system. The other is t h e user system prevents user programs accessing and possibly
stack pointer and is associated w i t h programs running under corrupting the operating system's stack. Only one of these
the operating system. The operating system controls t h e t w o A7s is accessible at a t i m e , because t h e 68K is either
allocation of t h e computer's resources ( m e m o r y and I/O), and running an operating system or it isn't.

Microprocessors don't implement a stack in this way and simultaneously, because all its address registers can be used as
the items already on the stack don't move as new items stack pointers.
are pushed and old ones pulled. The stack is located in a In what follows, we use the 68K's stack pointer to illustrate
region of the main store and a stack pointer points to the the operation of a stack. You might expect the assembly lan-
top of the stack. This stack pointer points at the top of guage instruction that pushes the contents of DO on the stack
stack as the stack grows and contracts. In some micro- to be PUSH DO, and the corresponding instruction to pull an
processors, the stack pointer points to the next free location item from the stack and put it in DO to be PULL DO. Explicit
on the stack, whereas in others, it points to the current top PUSH and PULL instructions are not provided by the 68K. You
of stack. can use address register indirect with predecrementing
Figure 6.27 demonstrates how the program illustrated in addressing mode to push, and address register indirect with
Fig. 6.26 is executed by a computer with a stack in memory postincrementing addressing mode to pull.
and a stack pointer, SP. Figure 6.28 illustrates the effect of a PUSH DO instruction,
The 68K doesn't have a special system stack pointer—it which is implemented by MOVE.W DO, — (SP), and PULL
uses address register A7. We call A7 the system stack pointer DO, which is implemented by MOVE, w (SP) + , DO. The 68K's
because the stack pointed at by A7 stores return addresses stack grows towards lower addresses as data is pushed on it;
during subroutine calls. Assemblers let you write either A7 or for example, if the stack pointer contains $80014C and a
SP; for example, MOVE, w DO, (A7) and MOVE, w DO, (SP) word is pushed onto the stack, the new value of the stack
are equivalent. The 68K can maintain up to eight stacks pointer will be $80014A.
6.5 The stack 265

The 68K's push operation MOVE. w DO, - (SP) is denned


in RTL as

[SP] «- [SP] - 2 Predecrement s t a c k p o i n t e r t o p o i n t t o n e x t f r e e element


[[SP]] <- [DO] Copy c o n t e n t s of DO t o t h e s t a c k

and the 68K's pull operation MOVE.W ( S P ) + ,D0 is


defined as

[DO] <- [ [ S P ] ] Copy t h e e l e m e n t on t o p of t h e s t a c k t o DO


[SP] <- [SP] + 2 P o s t i n c r e m e n t t h e s t a c k p o i n t e r t o p o i n t t o t h e new TOS

Push and pull operations use word or longword operands. system stack pointer, A7. The reason for this restriction is
A longword operand automatically causes the SP to be that A7 must always point at a word boundary on an even
decremented or incremented by 4. Address registers AO to A6 address (this is an operational restriction imposed by the
may be used to push or pull byte, . B, operands—but not the 68K's hardware).
The 68K's stack pointer is decre-
. mented before a push and incremented
N-4 N-4 after a pull. Consequently, the stack
N-2 pointer always points at the item at the
A7 A7 , - J ^ i * Top of stack
N
N , Top of stack N-2 J N top of the stack; for example,
N + 2 N + 2
Stack pointe r Stack pointe r MOVE ( S P ) + , D3 pulls the top item off
Stack Stack the stack and deposits it in D3. Note
N +6 N +6 that MOVE (SP) ,D3 copies the TOS
N +8 N+8 into D3 without modifying the stack
pointer.
U—: ^ When the stack shrinks after a
(a) Snapshot of the 68K's stack. (b) State of the stack after pushing a
word by MOVE.W D 0 , - ( A 7 ) . MOVE . w ( S P ) +, DO operation, items
on the stack are not physically deleted;
Figure 6.28 The 68K's stack. they are still there in the memory until
overwritten by, for example, a
MOVE.W DO, - (SP) operation.
Memory Memory The stack can be used as a temp-
orary data store. Executing a
Stack pointer MOVE.W DO, — ( S P ) saves the contents
A7 21DC DO 2 IDC of DO on the stack, and executing a
/ Dl 21E0 MOVE . W ( SP) + , DO returns the con-
Registers DO to D 5 / D2 21E4 tents of DO. The application of the stack
and A2 to A5 are D3 21E8 as a temporary storage location avoids
dumped on the stack D4 21EC storing data in explicitly named mem-
D5 21F0 ory locations. More importantly, if fur-
A2 21F4 ther data is stored on the stack, it does
A3 21F8 not overwrite the old data.
Stack pointer A4 21FC The 68K has a special instruction
A7' 2200 —*• Top of stack 22003 A5 2200 called move multiple registers (MOVEM),
— -— ^ which saves or retrieves an entire group
of registers. For example MOVEM.L
(a) Initial state of stack. (b) State of stack after MOVEM . L DO -D5 / D0-D7/A0-A7, - (A7) pushes all
A2-A5,-(A7). registers on the stack pointed at by A7.
The register list used by MOVEM is writ-
Figure 6.29 The 68K's stack. ten in the form D i - D j / Ap-Aq and
266 Chapter 6 Assembly language programming

SIMULATED INPUT AND OUTPUT

Microprocessors cannot perform input operations from the operations that the operating system can perform, you need
keyboard or display data on the screen. To do that requires an to tell the operating system what you want. EASy68K and the
operating system, peripherals, and their drivers. Teesside simulator use data register DO to hold a parameter
In order to allow the assembly language programmer to that defined the requested operation; for example, if you load
write programs that do have input or output operations, DO with 5, the request is for input.
simulators provide an I/O mechanism. Both EASy68K and the This I/O mechanism is specific to EASy68K and the Teesside
Teesside simulator use the 68K's TRAP #15 instruction.This simulator. It is part of their environment and will not work
instruction is a request to the operating system to provide a with any other 68K system.
facility such as input or output. Because there are many

specifies data registers Di to Dj inclusive and address registers uses an absolute address and cannot therefore be used to gen-
Ap to Aq inclusive. Groups of registers are pulled off the stack erate position-independent code. JSR may use an address reg-
by, for example, MOVEM.L (A7) + . D 0 - D 2 / D 4 / A 4 - A 6 . ister indirect address; for example, JSR (AO) calls the
The most important applications of the stack are in the subroutine whose address is in AO.
implementation of subroutines (discussed in the following
section) and in the handling of interrupts. When autodecre- Using subroutines—an example
menting is used, registers are stored in the order A7 to AO We now look at an example of how subroutines are used. The
then D7 to DO with the highest numbered address register following program inputs text from the keyboard and stores
being stored at the lowest address. Figure 6.29 illustrates the successive characters in a buffer in memory until an @ sym-
effect of MOVEM.L D 0 - D 5 / A 2 - A 5 , - (A7). bol is typed. When an @ is encountered, the text is displayed
on the screen. In this simple example, we don't test for buffer
overflow.
6.5.2 The stack and subroutines In this example we use the character input and output
mechanisms built into both EASy68K and the Teesside 68K
A subroutine is called by the instruction BSR < l a b e l > or JSR simulators. All I/O is performed by means of a TRAP #15
< l a b e l > , where BSR means branch to subroutine and JSR instruction, which is a call to the operating system. We have't
means jump to subroutine. The difference between BSR and yet covered the 68K's TRAP instructions, but all we need say
JSR is that BSR uses a relative address and JSR an absolute here is that a TRAP calls a function that forms part of the
address. Remember that the programmer simply supplies the computer's operating system. Before the TRAP is executed,
label of the subroutine and the assembler automatically calcu- you have to tell the O/S what operation you want by putting a
lates the appropriate relative or absolute address. To call a sub- parameter in data register DO. A '5' indicates character input
routine ABC, all we have to do is write either BSR ABC or JSR and a '6' indicates character output. When a character is
ABC. The BSR is preferred to J S R because it permits the use of input, it is deposited in Dl. Similarly, the character in Dl is
position-independent code. The range of branching with BSR is displayed by the output routine.
—32 kbytes to +32 kbytes from the present instruction. JSR We can express the algorithm is pseudocode as follows.

Initialize a pointer to point to the top of the character buffer


REPEAT
Read a character from the keyboard
Store it in the buffer at the address given by the pointer
Update the pointer
UNTIL character = "@"
Reset the pointer to point to the top of the character buffer
REPEAT
Read a character from the buffer at the address given by the pointer
IF character = "8" THEN exit
Display the character on the screen
Update the pointer
UNTIL exit
6.5 The stack 267

In the following program, the BUFFER is a region of memory When an RTS instruction is encountered at the end of a
reserved for the data to be stored. subroutine, the longword address on the top of the stack is

ORG $000400 Define the origin for data


LEA BUFFER(PC) A0 Preset A0 as a pointer register
NEXTIN BSR GET_CHAR Get a character
MOVE.B Dl, (A0) + Store character and move pointer to next
CMP.B #•e•,DI IF character = '@* THEN print
BNE NEXTIN ELSE repeat
PRINT LEA BUFFER(PC) A0 Reset pointer to start of buffer
NEXTOUT MOVE.B (A0)+,D1 Get a character and update pointer
CMP.B #'@',Dl IF character = '@' THEN EXIT
BEQ DONE
BSR PUT CHAR ELSE print character
BRA NEXTOUT Repeat
DONE STOP #$2700 Halt the 68K
*
GET CHAR MOVE.B #5,DO Input routine (code = 5)
TRAP #15 Load input command in DO and call O/S
RTS Return

PUT CHAR MOVE.B #6, DO Output routine (code = 6)


TRAP #15 Load output command in DO and call O/S
RTS Return

ORG $500
BUFFER DS.B 40 Reserve 40 bytes of storage
END $400

The instruction CMP. B # ' @', Dl compares the contents pulled and placed in the program counter in order to force a
of the lower-order byte of data register Dl with the byte return to the calling point. The following code is produced
whose ASCII code corresponds to the symbol @. The instruc- by assembling this program. We will need this output
tion LEA BUFFER (PC) , AO generates position-independent when we trace the program (in particular the addresses
code because it calculates the address of the buffer relative to of the subroutines and the return addresses of subroutine
the program counter. Had we written LEA BUFFER, AO, the calls).
code would not have been position independent.

1 00000400 ORG $000400 ; Define the origin for data


2 00000400 41FA0OFE LEA BUFFER(PC),A0 ; Preset A0 as pointer r e g i s t e r
3 00000404 61000022 NEXTIN: BSR GET_CHAR Get a character
4 00000408 10C1 MOVE.B Dl, (A0) + Store character and move pointer to next
5 0000040A 0C010040 CMP.B #'@',Dl IF character = '%' THEN p r i n t
6 0000040E 66F4 BNE NEXTIN ELSE repeat
7 00000410 41FA00EE PRINT: LEA BUFFER(PC),A0 ;Reset pointer to start of buffer
8 00000414 1218 NEXTOUT: MOVE.B (A0)+,D1 Get a character and update pointer
9 00000416 0C010040 CMP.B # ' @',Dl IF character = '@' THEN EXIT
10 0000041A 67000008 BEQ DONE
11 0000041E 61000010 BSR PUT_CHAR ELSE print character
12 00000422 60F0 BRA NEXTOUT ; Repeat
13 00000424 4E722700 DONE: STOP #$2700 Halt the 68K
14
15 00000428 103C0005 GET_CHAR: MOVE. B #5, DO Input routine
16 0000042C 4E4F TRAP #15 Load input command in DO and call O/S
17 0000042E 4E75 RTS ;Return
18 *
19 00000430 103C0006 PUT_CHAR: MOVE.B #6, DO Output routine
20 00000434 4E4F TRAP #15 Load output command in DO and call O/S
21 00000436 4E75 RTS ;Return
22 *
23 00000500 ORG $500
24 00000500 00000028 BUFFER: DS.B 40 /Reserve 40 bytes of storage
25 00000400 END $400
268 Chapter 6 Assembly language programming

The following trace output demonstrates the flow of


control as subroutine calls and subroutine returns are
made—when you read the trace, look at the program counter
and the stack pointer (A7 = SS). Remember that the PC is
incremented between 2 and 10 bytes after each instruction.

P C = 0 0 0 4 0 0 ^ 5 g = 2 0 0 0 SS=00AO00OO U S = 0 0 0 0 0 0 0 0 X=0
AO = OOOOOOOOAT5l>eAQiiOOO A2 = 0 0 0 0 0 0 0 0 A3 = 0 0 0 0 0 0 0 0 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 ? t r f t ^ i a £ 0 0 0 0 0 0 A 7 = 0 0 A 0 0 0 0 0 Z=0
D0 = 0 0 0 0 0 0 0 0 D1 = 0 0 0 0 0 0 0 0 D2 = 0OO0TJtT&«-J2^=0000000O V=n .
D4 = 0 0 0 0 0 0 0 0 D 5 = 0 0 0 0 0 0 0 0 D6 = 0 0 0 0 0 0 0 0 D7^ITCrfr9*LCLQ0C= Note the position independent
>LEA.L $FE(PCJ AO " code. The value of the PC when
^~i , LEA $FE(PC),AO is executed
P C = O O O 4 0 4 S R = 2 0 O O SS=OOAOOOOO us=oooooooo x= '^f402^ Th^°"se*,s°0FEi6/;so
^ the value loaded into AO is
an-nnnnnRnn«rn nnnnnnnn in.nnnnnnnn 3Vfl0000000 N= ^2 +FE =500,6
A4 = 0 0 0 0 0 0 0 0 A5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7 = 00AOOOO0 Z = L _ _ ! ! _ J _ _
D 0 = 0 0 0 0 0 0 0 0 D 1 = 0 0 0 0 0 0 0 0 D 2 = 0 0 0 0 0 0 0 0 D 3 = 0 0 0 0 0 0 0 0 V=0
D 4 = 0 0 0 0 0 0 0 0 D 5 = 0 0 0 0 0 0 0 0 D 6 = 0 0 0 0 0 0 0 0 D 7 = 0 0 0 0 0 0 0 0 C=0
>BSR.L $0428

We've set A0 to point to the buffer for input data. The next
instruction calls the subroutine to input a character. Note the
change in the PC to $428.

PC=000428 SR=2000 SS=009FFFJC US=00000000 X=0 0 0 9FFFFC:00000408 s


A0=00000500 A1=00000000 A2=00TTtn»&e—£3^00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7^CTD?FFFEC_^0 Note the stack pointer
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V^0~" has moved up 4 bytes
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 and the return address
>MOVE.B #$05,DO
is on the stack.
PC=00042C SR=2000 SS=009FFFFC US=00000000 X=0 009FFFFC:00000408 s
A0=00000500 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=009FFFFC Z=0
D0=00000005 D1=00000000 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>TRAP #$0F

This is the character entered from the keyboard and captured by the TRAP #15.

C=00042E SR=2000 SS=009FFFFC US=00000000 X=0 009FFFFC:00000408 s


A0=00000500 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=009FFFFC Z=0
D0=00000005 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>RTS

Having got the input (in this case Z) in Dl, we return from
the subroutine. Watch the program counter again. It is
currently $42E and will be replaced by $408 (i.e. the address
of the instruction after the subroutine call.

PC=000408 SR=2000 SS=O0AO0O0O US=00000000 X=0


A0=00000500 A1=00000000 A2-00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=O0A00O00 Z=0
D0=00000005 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>MOVE.B D1,(A0)+
6.5 The stack 269

We now store the character in Dl in memory and


increment the pointer in AO.

PC=00040A SR=2000 SS=00A00000 US=00000000 X=0


A0=00000501 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=00A00000 Z=0
D0=00000005 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>CMPI.B #$40,Dl

PC=00040E SR=2000 SS=00A00000 US=00000000 X=0


A0=00000501 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=00A00000 Z=0
D0=00000005 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 00
>BNE.S $0404

We test the character in D1 for equality with '@' = $40 and


then branch back to $0404 if we haven't input an '@'.

PO000404 SR=2000 SS=00A00000 US=00000000 X=0


A0=00000501 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=0OAOO0OO Z=0
D0=00000005 D1=0000005A D2=00000000 D3=00000000 v=o
D4=00000000 D5=00000000 D6=00000000 D7=00000000 c=o
>BSR.L $0428

We haven't, so we continue by reading another character.

PC-000428 SR=2000 SS=009FFFFC US=00000000 X=0 009FFFFC:00000408 s


A0=00000501 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=009FFFFC Z=0
D0=00000005 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>MOVE.B #$05,DO

To avoid more tracing, we'll jump ahead to the point at


which a '@' has been input in DO.

P O 0 0 0 4 2 C SR=2000 SS=009FFFFC US=00000000 X=0 009FFFFC:00000408 s


A0=00000501 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=009FFFFC Z=0
D0=00000005 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>TRAP #$0F

PC=OO^M2X^R^2TTO«--SS^I1£9TFFFC US=00000000 X=0 009FFFFC: 00000408 s


A0=00000502 Al=00000000~A2^0lKTTO^e«-Aa£00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=009FFF
Here's the '@' that
D0=00000005 m=nnnnnn/in.-,n->-n^nnnnnn n^nnnnnnnn V =o
D4=00000000 D5=00000000 D6=00000000 D7=0 we entered and its
>RTS ASCII value in Dl.

PC=000408 SR=2000 SS^OOAOOOOO OS=00000000 X=0


A0=00000502 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=00A00000 Z=0
D0=00000005 Dl=00000040 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>MOVE.B D1,(A0)+
270 Chapter 6 Assembly language programming

PC=00040A SR=2000 SS=OOAO00O0 US=00000000 X=0


A0=00000503 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=OOAOO0OO Z=0
D0=00000005 Dl=00000040 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>CMPT.B #540,Dl

PC=00040E SR=2004 SS=00A000O0 US=O0OO0000 X=0


A0=00000503 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=0OA0O00O Z=l
D0=00000005 Dl=00000040 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>BNE.S $0404

Because D l contains the ASCII code for'@', the test for equal-
ity will yield true and we will not take the branch back to $0404.

P O 0 0 0 4 1 0 SR=2004 SS=00A00000 US=00000000 X=0


A0=00000503 A1=00000000 A2=00000000 A3=00000000 N=0
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=00A00000 Z=l
D0=00000005 Dl=00000040 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>LEA.L $EE(PC),A0

T h e next instructions reset the pointer to the top of the


buffer, read a character, a n d compare it to '@'.

PC=000414 SR=2004 SS=O0AOO0OO US=00000000 X=0


A0=00000500 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=O0AOO000 Z=l
D0=00000005 Dl=00000040 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>MOVE.B (A0)+,D1

PC=000416 SR=2000 SS=OOA0O0OO US=00000000 X=0


A0=00000501 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=O0AO0OOO Z=0
D0=00000005 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>CMPI.B #$40,Dl

PC=00041A SR=2000 SS=00A00000 US=00000000 X=0


A0=00000501 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=00A00000 Z=0
D0=00000005 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>BEQ.L $0424

If it isn't an '<§>', we will print it by calling the o u t p u t routine.

PC=00041E SR=2000 SS=0OAOO00O OS=00000000 X=0


A0=00000501 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=O0AOOO0O Z=0
D0=00000005 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>BSR.L $0430
6.5 The stack 271

PC=000430 SR=2000 SS=009FFFFC US=00000000 X=0 009FFFFC:00000422 s


A0=00000501 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=009FFFFC Z=0
D0=00000005 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>MOVE.B #$06,DO

In this case we have branched to address $0430.

P O 0 0 0 4 3 4 SR=2000 SS=009FFFFC US=00000000 X=0 009FFFFC:00000422 s


A0=00000501 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=009FFFFC Z=0
D0=00000006 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>TRAP #$0F

We call the operating system with the TRAP. Note that the
contents of D1 will be printed as the ASCII character Z. Then
we return to the body of the program.

© PC=000436 SR=2000 SS=009FFFFC US=00000000 X=0 009FFFFC-.00000422 s


A0=00000501 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=009FFFFC Z=0
D0=00000006 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>RTS

Note the change in the value of the PC following the RTS.

PC=000422 SR=2000 SS=O0AO0OOO US=00000000 X=0


A0=00000501 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=00A00000 Z=0
D0=00000006 D1=0000005A D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>BRA.S $0414

And so on ..

6.5.3 Subroutines, the stack, and


pressed. A return to the calling point is made with the ASCII
parameter passing code of the character in data register D1.
In order for a subroutine to carry out its function, it is almost You can even use the C-bit in the CCR to pass informa-
always necessary to transfer data between the calling program tion from a subroutine to its calling program; for example,
and the subroutine. Up to now we have passed data to and from to indicate an error state. Suppose a subroutine has been
the subroutine via data registers. In the previous example, we called to read data from a terminal and the terminal is faulty
called the subroutine GET_CHAR to input a character from the or not switched on. By setting the carry bit prior to a return
keyboard. When this subroutine is invoked by the operation from subroutine, the calling program can be informed that
BSR GET_CHAR, a branch is made to the entry point of the sub- an error exists as the following fragment of a program
routine. This subroutine reads the keyboard until a key is demonstrates.
272 Chapter 6 Assembly language programming

BSR GETDATA Call subroutine and return with data in DO


BCS ERROR IF carry flag set THEN something went wrong

ELSE deal with the data

ERROR Recover from error condition

You can't use registers to transfer large quantities of data to above the top of the stack). If an interrupt occurs or you call
and from subroutines, due to the limited number of registers. a subroutine, the new return address will be pushed on the
You can pass parameters to a subroutine by means of a mail- top of the stack overwriting the old return address. Never
box in memory. Consider the following. move the stack pointer below the top of stack.

MOVE.W Paraml,Mboxl Put first parameter in mail box 1


MOVE.W Param2,Mbox2 Put second parameter in mail box 2
BSR Sub Now call the subroutine
Return here...

Sub MOVE.W Mboxl,DO Retrieve the first parameter


MOVE.W Mbox2,Dl Retrieve the second parameter

RTS Return to the calling program

Such a solution is poor, because the subroutine can't be You can avoid using the stack pointer by copying it to
interrupted or called by another program. Any data stored in another address register with LEA (A7) , AO. NOW you can
explicitly named locations could be corrupted by the inter- use AO to get the parameters; for example, PI can be loaded
rupting program (see the box on interrupts). Let's look at into Dl by MOVE.W 6(A0) ,D1. The offset 6 is required
how data is transferred between a subroutine and its calling because the parameter PI is buried under the return address
program by many high-level languages. (4 bytes) and PI (2 bytes). Similarly, P2 can be loaded into D2
by MOVE.W 4(AO) ,D2.
Passing parameters on the stack After returning from the subroutine with RTS, the contents of
An ideal way of passing information between the subroutine the stack pointer are [A7] — 4, where A7 is the value of the stack
and calling program is via the stack. Suppose two 16-bit pointer before PI and P2 were pushed on the stack. The stack
parameters, PI and P2, are needed by the subroutine pointer can be restored to its original value or cleaned up by exe-
ABC(P1,P2). The parameters are pushed on the stack cuting LEA 4 (A7) , A7 to move the stack pointer down by two
immediately before the subroutine call by the following code: words. Note that LEA 4 (A7) , A7 is the same as ADD . L # 4, A7.
PI and P2 are, of course, still in the same
locations in memory but they will be over-
MOVE.W P 1 , - ( A 7 ) Push the first parameter on t h e s t a c k written as new data is pushed on the stack.
MOVE. W P 2 , - ( A 7 ) Push the second parameter
BSR ABC Call ABC(P1,P2) By using the stack to pass parameters to
a subroutine, the subroutine may be inter-
The state of the stack prior to the subroutine call and rupted and then used by the interrupting program without
immediately after it is given in Fig. 6.30. Note that the return the parameters being corrupted. As the data is stored on the
address is a longword and takes up two words on the stack. stack, it is not overwritten when the subroutine is interrupted
On entering the subroutine, you can retrieve the parame- because new data is added at the top of the stack, and then
ters from the stack in several ways. However, you must never removed after the interrupt has been serviced.
change the stack pointer in such a way that you move it down Let's look at another example of parameter passing in detail.
the stack. Consider Fig. 6.30(c) where the stack pointer is In the following program two numbers are loaded into DO and
pointing at the return address. If you add 4 to the stack Dl, and then the contents of these registers are pushed on the
pointer, it will point to parameter P2 on the stack. You can stack. A subroutine, Addup, is called to add these two numbers
now get P2 with, say, MOVE. W (A7) , DO. However, the return together. In this case the result is pushed on the stack. We've used
address is no longer on the stack (it's still there in memory blue to highlight code that performs the parameter passing.
6.5 The stack 273

(a) Initial state of the stack. (b) Immediately before BSR. (c) immediately after BSR.
Stack Stack Stack Address with
respect to the
stack pointer
return
° /

address
J>2

Stack pointer Stack pointer


PI
P2
P1 +
+6
y
Stack pointer
TOS
n-4 +8

figure 6.30 Passing parameters on the stack (all values on the stack are words or longwords).

THE INTERRUPT
An interrupt is a method of diverting the processor from its explicitly named memory locations will be overwritten and
intended course of action, and is employed to deal with errors corrupted by the re-use of the subroutine. If the data had been
and external events that must be attended to as soon as they stored in registers and the content of the registers pushed on
occur. Whenever a processor receives an interrupt request the stack by the interrupt-handling routine, no data in the
from a device, the processor finishes its current instruction and subroutine would have been lost by its re-use. After the sub-
then jumps to the program that deals with the cause of the routine has been re-used by the interrupt-handling routine, the
interrupt. After the interrupt has been serviced, a return is contents of the registers stored on the stack are restored and a
made to the point immediately following the last instruction return from interrupt is made with the state of the registers
before the interrupt was dealt with. The return mechanism of exactly the same as at the instant the interrupt was serviced.
the interrupt is almost identical with that of the subroutine— Interrupts may originate in hardware or software. A
the return address is saved on the stack. hardware interrupt may occur when you move the mouse.
Suppose a subroutine is interrupted during the course of its A software interrupt may occur when you perform an illegal
execution. If the interrupt-handling routine also wishes to use operation or even when you generate one with a TRAP #15
the same subroutine (yes, that's possible), any data stored in instruction.

ORG $400
LEA $1000,A7
MOVE W #l,DO Set up the stack pointer
MOVE W #2,D1 Set up two parameters in DO and Dl

MOVE W D0,-(A7) Push parameter 1 on the stack


MOVE w D1,-(A7) Push parameter 2 on the stack

BSR AcidUp Call adder routine


MOVE w (A7)+,D2 Read the result from the stack
LEA 2<A7) , A 7 Clean up the stack
STOP #$2700 Stop

AcidUp MOVE w 4(A7),D2 Get parameter 2 from the stack


MOVE w 6(A7) ,D3 Get parameter 1 from the stack
ADD.W D2,D3 Add them
MOVE w D3,4(A7) Store the r e s u l t in the parameter 2 s l o t
RTS

If we assemble this program, we get the following.

1 00000400 ORG $400


2 00000400 4FF81000 LEA $1000,A7 ;Set up the stack pointer
3 00000404 303C0001 MOVE W #1,D0 ;Set up two parameters in DO and Dl
4 00000408 323C0002 MOVE W #2,D1
5 0000040C 3F00 MOVE .W D0,-(A7) ;Push parameter 1
274 Chapter 6 Assembly language programming

6 0000040E 3F01 MOVE .W D1,-(A7) ;Push parameter 2


7 00000410 6100000C BSR ADDUP ;Call adder routine
8 00000414 381F MOVE w (A7)+,D4 ;Read the result
9 00000416 4FEF0002 LEA 2(A7),A7 ;Clean up stack
10 0000041A 4E722700 STOP #$2700 ;Stop
11
12 0000041E 342F0004 ADDUP: MOVE w 4(A7),D2 Get parameter 2
13 00000422 362F0006 MOVE w 6(A7),D3 Get parameter 1
14 00000426 D642 ADD D2,D3 Add them
15 00000428 3F430004 MOVE w D3,4(A7) Store r e s u l t in the parameter 2 s l o t
16 0000042C 4E75 RTS
17
18 00000400 END $400

Figure 6.31 shows the state of the stack at various points


during the execution of this program. We will now load the
program and trace it line by line.

PC=000400 SR=2000 SS=00A00000 US=00000000 X=0


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=OOA0OOO0 Z=0
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>LEA.L $1000,SP

PC=000404 SR=2000 SS=00001000 US=00000000 X=0 00001000:00000000 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00001004:00000000 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00001000 Z=0 00001008:00000000 s+8
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V=0 0000100C:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001010:00000000 s+16
>MOVE.W #$01,DO

Note the five new entries to the right of the register display.
These lines display the five longwords at the top of the stack.
Each line contains the stack address, the longword in that
address, and the address with respect to the current stack
pointer.

Stack Stack

P2=2 0FFC

P1=1 OFFE OFFE


Stack pointer Stack pointer Stack pointer
TOS 1000
$1000 $0FF£ 1000 1000
SOFFE

(a) Initial state of the stack. (b) After pushing P1 w i t h (c) After pushing P2 with
MOVE.W D 0 , - ( A 7 ) . MOVE.W D 0 , - ( A 7 ) .
Stack Stack Stack

Return
/address Offset f r o m 0FF8
SP
r*t»000414 0FF8 OFFE 30000414 0 0FFC
0FFC
'*S
P2=2 0FFC P2=2 +4 P2=2 OFFE
P1=1 OFFE OFFE P1=1 +6 P1=1 1000
Stack pointer Stack pointer Stack pointer
1000 +8
$0FF8 S0FF8 $0FFC
Figure 6.31 The state of the
(d) After calling the subroutine. (d) Accessing parameters
(d) After returning from stack during the execution of a
in the subroutine.
the subroutine. program.
6.5 The stack 275

PC=000408 SR=2000 SS=00001000 US=00OO0OO0 X=0 00001000:00000000 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00001004:00000000 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00001000 Z=0 00001008:00000000 s+8
DO-00000001 Dl=O0O0OO0O D2=00000000 D3=00000000 V=0 0000100C:00000000 s+12
D4=0OO000O0 D5=00000000 D6=00000000 D7=00000000 C=0 00001010:00000000 s+16
>MOVE.W #$02,Dl

PC=00040C SR=2000 SS=00001000 US=00000000 X=0 00001000:00000000 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00001004:00000000 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00001000 Z=0 00001008:00000000 s+8
D0=00000001 Dl=00000002 D2=00000000 D3=00000000 V=0 0000100C:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001010:00000000 s+16
>MOVE.W DO,-(SP)

PC=00040E SR=2000 SS=O0000FFE US=00000000 X=0 00000FFE:OOO10O00 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00001002:00000000 s+4
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=0OOOOFFE Z=0 00001006:00000000 s+8
D 0 = 0 0 0 0 0 0 0 1 D l = 0 0 0 0 0 0 0 2 D 2 = 0 0 0 0 0 0 0 0 D3=00000000 V=0 0000100A:00000000 s+12
D4=00000000 D 5 = 0 0 0 0 0 0 0 0 D6=00000000 D7=00000000 C=0 0000100E:00000000 s+16
>MOVE.W D1,-(SP)

Note how the instruction MOVE. w DO,— (SP) has mod-


ified the stack. The top of the stack is no longer $1000, but
$0FFE. You can also see that the contents of DO.W (i.e. 0001)
has been pushed on the stack.

PC=000410 SR=2000 SS=00000FFC US=00000000 X=0 00000FFC:OO020001 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00001000:00000000 s+4
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=00000FFC Z=0 00001004:00000000 s+8
D0=00000001 Dl=00000002 D2=00000000 D3=00000000 V=0 00001008:00000000 s+12
D4=00000000 D 5 = 0 0 0 0 0 0 0 0 D 6 = 0 0 0 0 0 0 0 0 D7=00000000 C=0 0000100C:00000000 s+16
>BSR.L $041E

PC=00041E SR=2000 SS=00O0OFF8 US=00000000 X=0 O0000FF8:OOOOO414 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00000FFC.-00020001 s + 4
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7-0OOOOFF8 Z=0 0 0 0 0 1 0 0 0 : 0 0 0 0 0 0 0 0 s+8
D0=00000001 Dl=00000002 D2=00000000 D3=00000000 V=0 00001004:00000000 s+12
D4=00000000 D5=00000000 D 6 = 0 0 0 0 0 0 0 0 D7=00000000 C=0 00001008:00000000 s+16
>MOVE.W $04(SP),D2

At this point the return address, $00000414, has been


pushed on the stack and the stack pointer is now pointing at
$00000FF8.

PC=000422 SR=2000 SS=00000FF8 US=00000000 X=0 00000FF8:00000414 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00000FFC:00020001 s+4
A4=00000000 A5=00000000 A6=00000000 A7=0000OFF8 Z=0 00001000:00000000 s+8
D0=00000001 Dl=00000002 D2=00000002 D3=00000000 V=0 00001004:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001008:00000000 s+16
>MOVE.W $06(SP),D3

PC=000426 SR=2000 SS=O0OOOFF8 US=00000000 X=0 OOOOOFF8:00000414 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 OOOOOFFC:00020001 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00000FF8 Z=0 00001000:00000000 s+8
D0=00000001 Dl=00000002 D2=00000002 D3=00000001 V=0 00001004:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001008:00000000 s+16
>ADD.W D2,D3
276 Chapter 6 Assembly language programming

PC=000428 SR=2000 SS=00000FF8 US=00000000 X=0 OOOOOFF8:00000414 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00000FFC:00020001 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00000FF8 Z=0 00001000:00000000 s+8
D0=00000001 Dl=00000002 D2=00000002 D3=00000003 V=0 00001004:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001008:00000000 s+16
>MOVE.W D3,$04(SP)

PC=00042C SR=2000 SS=00000FF8 US=00000000 X=0 OOOOOFF8:00000414 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 OOOOOFFC:00030001 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00000FF8 Z=0 00001000:00000000 s+8
D0=00000001 Dl=00000002 D2=00000002 D3=00000003 V=0 00001004:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001008:00000000 s+16
>RTS

PO000414 SR=2000 SS=00000FFC US=00000000 X=0 O00O0FFC:0OO3O001 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00001000:00000000 s+4
A4=00000000 A5=00000000 A6=00000000 A7=OOO0OFFC Z=0 00001004:00000000 s+8
D0=00000001 Dl=00000002 D2=00000002 D3=00000003 V=0 00001008:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 0000100C:00000000 s+16
>MOVE.W (SP)+,D4

PC=000416 SR=2000 SS=0O0OOFFE US=00000000 X=0 OOCOOFFE:00010000 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00001002:00000000 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00000FFE Z=0 00001006:00000000 s+8
D0=00000001 Dl=00000002 D2=00000002 D3=00000003 V=0 0000100A:00000000 s+12
D4=00000003 D5=00000000 D6=00000000 D7=00000000 C=0 0000100E:00000000 s+16
>LEA.L $02(SP),SP

PC=00041A SR=2000 SS=00001000 US=00000000 X=0 00001000:00000000 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00001004:00000000 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00001000 Z=0 00001008:00000000 s+8
D0=00000001 Dl=00000002 D2=00000002 D3=00000003 V=0 0000100C:00000000 s+12
D4=00000003 D5=00000000 D6=00000000 D7=00000000 C=0 00001010:00000000 s+16
>STOP #$2700

Passing parameters by reference


The result 1 + 2 = 3 is in data register D3, and the stack We have passed a parameter by value to the subroutine by
pointer is the same as its starting value $1000. Passing a para- pushing a copy of its value on the stack. There are two copies
meter to a subroutine by value is easy. Getting a result back of the parameter, the original in the calling program and its
from the subroutine is trickier, as we'll soon see. copy on the stack. If a parameter is passed by value, changing
it within the subroutine doesn't change its value in the calling
program—as the next example demonstrates.

Program to call a subroutine that swaps two numbers A and B

ORG $400
LEA $1000,A7 Set up the stack pointer
MOVE.• W A,-(A7) Push value of parameter A
MOVE..W B,-(A7) Push value of parameter B
BSR SWAP Call subroutine to swap A and B
LEA 4(A7),A7 Clean up the stack
STOP #$2700 Stop

SWAP MOVE.W 4(A7),D1 Get first parameter in DO


MOVE.W 6(A7),4(A7) Copy second parameter to first parameter
MOVE.W D1,6(A7) Copy first parameter to second parameter
RTS

A DC.W $1234
B DC.W $5678

END $400
6.5 The stack 277

This program calls a subroutine to swap two numbers, In this case, there is only one copy of the parameter. We repeat
A and B, which are first pushed on the stack in the main pro- the example in which we added two numbers together, and, this
gram. In subroutine SWAP the two parameters are retrieved time, pass the parameters to the subroutine by reference.
from their locations on the stack and swapped over. Once a The following program introduces a new instruction,
return from subroutine is made and the stack cleaned up, the push effective address PEA, which pushes an address in the
parameters on the stack are lost. Parameters A and B in the stack; for example, the operation PEA PQR pushes the address
main program were never swapped. PQR on the stack. The instruction PEA PQR is equivalent to
MOVE.L #PQR, - (A7).

ORG $400
LEA $1000,A7 Set up the stack pointer
PEA X Push address of variable X
PEA X Push address of variable Y
PEA Z Push address of variable 2 (the- result;':
BSR AddUp Call adder routine
MOVE.W Z,D2 Read the result (a dummy operation)
LEA 12(A7),A7 Clean up stack
STOP #$2700 Stop
*
AddUp HOVEA.L 12(A7),A0 Get address of parameter X
MOVKA.L S(A7),A1 Get address of parameter Y
MOVE. Vi (AD) ,D2 Get value of X
MOVE.W (All,D3 Get value of Y
ADD D2,D3 Add them
MOVEA.L 4(A7),A3 Get address of parameter Z
MOVE.W D3, (A3) Put result in variable Z
RTS
*
ORG $500
X DC.W 1
Y DC.W 2
Z DS.W i

You can pass a parameter to a subroutine by reference by pass- The following is the assembled version of this program and
ing its address on the stack. This is, you don't say'Here's a para- Fig. 6.32 provides snapshots of memory and registers during
meter'. Instead you say, 'Here's where the parameter is located'. the execution of the code.

1 00000400 ORG $400


2 00000400 4FF81000 LEA $1000,A7 ;Set up the stack p o i n t e r
3 00000404 487900000500 PEA X ;Push address of X
4 0000040A 487900000502 PEA Y ,-Push address, of Y
5 00000410 487900000504 PEA Z ;Push address of Z
6 00000416 61000010 BSR ADD0P /Call adder routine
7 0000041A 343900000504 MOVE.W Z,D2 /Read the result ••
8 00000420 4FEF000C LEA 12(A7),A7 ;Clean u p stack
9 00000424 4E722700 STOP #$2700 •/Stop
10 *
11 00000428 206F0O0C ADDDP: ' MOVEA.L 12(A7),A0 ;Get address of parameter
12 0000042C 226F0008 MOVEA.L 8{A7),A1 ;Get address pf parameter •
13 00000430 3410 MOVE.W <A0),D2 ;Get value of X
14 00000432 3611 MOVE.W (A1),D3 ./Get v a l u e of ; Y
15 . 00000434 D642 ADD D2,D3 /Add them
16 00000436 266F0004 MOVEA.L 4(A7),A3 /Get address o f p a r a m e t e r
17 0000Q43A 3683 .MOVE.W ' D3, (A3.) ;Put. result in v a r i a b l e .2
18 0000043C 4E75 RTS
19 . ,-• *
20 .00000500 O R G '•• $500
21 . 00000500 0001 X: : • ' DC.W :, '1
22, 00000502 0002 . T: . DP.W. : .2
23 00000504 0,0000002: Z: DS.W . 1 •

24 •...•; ': ' * .


25 • '•' 00000400,,' ' • 'END $400
278 Chapter 6 Assembly language programming

_ Memory

x osoo
0500
Y 0502
Z 0504

Stack Stack
_Stack Stack

r> Return OFFO


0S04 00FF4
FF4 :-• :J:\1l
r > __T___ 0-i
'-'St'2
:
- ••••••' 0FF8
OFFS •.'•:•.
••'-•' .-• c.-:;-.
c.-:;-.

r , . OSGO
c •::. OFFC ;.'::_0
;::•:.:.: OF'-,."
or-,:
Stack pointer
Stack pointer — — — Stack pointer ~ Stack pointer
A7 T S 1000 11000
000 100
A7[T^0~]-^] ° J [—r^ 1 IOOO
[E™3~Mz=d A7[i5if]J 1————j Ajfi^y
A7 SOFFO —I I [ °
(a) Initial state of the stack. (b) After pushing &X, &Y ((c)
c) A
After
f t e r ccalling Addllp
alling A cUUp
and &Z with PEA X, PEA Y, with BSR
with BSR addup.
addup.
v
PEAZ.
Memory
Memory Memory

X
X S^~~ -o~n~i0
f^p
1 ,
Addresses of
Addresses of
/ - Xx ^^- B
/~ ~S OO
TSEOO
V <—. rcA"> parameters loaded f! ,^ Addresses of
V <—. rcA-> parameters loaded
' -<^u u < i n a < j < | r e s s registers \\ jY iY ^—•
~*— 050£
050£ parameters loaded
parameters loaded
' -<f < i n a < j < | r e s s registers \ ^ \ in address registers
-, \ \ A1 and AO \ ^2,
_\ 0504\\ in address registers
AlandAO.
., \ \ Al and AO
__£__ 0504\ _\ ^ 0504 \ AlandAO.
Z 05CM\
' J-I \ MHi' JJ, W oos
5 l' ]J AO
A„ n_SZ3Zj
Z3Z] \',V.|ooooo5Qj)j
vjooooosoo IAi 0n
\ I 1-1 AO \ \ \ I 4I™
Stack
Stack \V I. -fLl , Sta-ckX \ i Li
v Z_r—]\ ^ oooqgsog AI
" — — 1i -^Quoojjp|
OvOOMiZ AA1
1 I——V-A "~- oooqgsy AI
"*0 RetumX cAo J j
•*•
• • °0 Return OFFO 1~~1
J~l -+.0 R e turn\ OF-0 * /
4
A •;•;• •: CFF4
;•;• .' CFF4 ./
yS II 4~7~ W-i\ y I
8 ''•-'(»- - Off ik N^
8 '-;:'--- - -dTS / g CLXt2 - Off!s, \ _
Stack . J e -f-' -• O f * S — ^ ^ ^ Stack ,2 05Ct'Ji)F-FGX | ~~ Y | -
pointer
nnfntr
"M — —
12 C1,Q:; - U f € — ^ pointer
Stack 'c
12 05Ct J ^ - F G X \ _ | ~ ~ V ^
ointer s
A 7 J PSOFFO I—i ••• pointer
A 7 |I—50FF0 |I - J
'^ — — — 1 0 C
[_ '°
\
x ")~~- X
,,„rf,.| 1000 TUQQ < ; 1\„?
A7| SOFFO |—' [ - j A 7 j $OFFO |—' —-—— j ~ ~ ~X |^?
(d)
(d) In subroutine AddUp after
In subroutine AddUp after , »,In subroutine
, .. AddUp. ..., after^ y'uc I , l S,c
(e) t ' t ! j't
MOVEA.L
MOVEA L 12 1 2 <(A7)
A7),A AO0 (e) In subroutine AddUp after „ < ,
MOVEA.L MOVE.W ( A 0 ) , D 2 i.wmory
l t d tuOata
MOVEA L B8 (( AA 77 )) ',AA11 . MOVE.W
MOVE . W (AO)
( A l ), D2
, D3 . memory
registers. toOata
MOVbA.I, B ( A 7 ) , A 1 . MOVE.W (A1),D3. registers.

Figure 6.32 Example of parameter passing by reference.

We can now run this program line by line. Note We will use the simulator command MD 500 to view the
how the addresses of the variables are pushed on the stack data area. Initially it contains the two 16-bit constants
and then loaded in address registers in the subroutine. 1 and 2.

000500 00 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00.

PO000400 SR=2000 SS=OOA0OOOO US=00000000 X=0


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0
A4=00000000 A5=00000000 A6=00000000 A7=00A00000 Z=0
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V=0
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0
>LEA.L 51000,SP

PC=000404 SR=2000 SS=00001000 US=00000000 X=0 00001000:00000000 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00001004:00000000 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00001000 Z=0 00001008:00000000 s+8
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V=0 0000100C:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001010:00000000 s+16
>PEA $0500

PC=00040A SR=2000 SS=O00O0FFC US=00000000 X=0 OOOOOFFC:00000500 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00001000:00000000 s+4
A4=00000000 A5=00000000 A6=00000000 A7=O0O00FFC Z=0 00001004:00000000 s+8
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V=0 00001008:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 0000100C:00000000 s+16
>PEA $0502
6.5 The stack 279

The operation PEA $ 0 5 0 0 has pushed the address


$00000500 on the stack and moved the stack pointer up by 4.

PO000410 SR=2000 SS-OO000FF3 US=00000000 X=0 G0000FFS:0CC00502 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00000FFC:00000500 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00000FF8 Z=0 00001000:00000000 s+8
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V=0 00001004:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001008:00000000 s+16
>PEA $0504

PO000416 SR=2000 3S=OOO00FF4 US=00000000 X=0 OOOOOFF4:00000504 s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00OOOFF8:OO0005O2 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00O00FF4 2=0 0000OFFC:0O0O05O0 s+8
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V=0 00001000:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001004:00000000 s+16
>BSR.L $0428

PO000423 SR=2000 SS = 0O0O0FFO US=00000000 X=0 0C000FF0:000C041A s


A0=00000000 A1=00000000 A2=00000000 A3=00000000 N=0 00000FF4:00000504 s+4
A4=00000000 A5=00000000 A6=00000000 A7=0OO00FF0 Z=0 00000FF8:00000502 s+8
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V=0 00000FFC:00000500 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001000:00000000 s+16
>MOVEA.L $0C (SP) ,A0

PO00042C SR=2000 SS=00000FF0 US=00000000 X=0 0O0OOFF0:000OO41A s


AO^OOOOOSOO A1=00000000 A2=00000000 A3=00000000 N=0 OOOOOFF4-.00000504 s + 4
A4=00000000 A5=00000000 A6=00000000 A7=OOOO0FF0 Z=0 0000OFF8:O00O05O2 S + 8
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V=0 00000FFC:00000500 s+12
D4-00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001000:00000000 s+16
>MOVEA.L $08(SP),Al

0 0 0 0 0 4 30 SR=2000 SS=D0000FF0 U S = 0 0 0 0 0 0 0 0 X=0 OOOOOFF0:00O0041A S


A0=00000500 A1=0C000502 A2=00000000 A3=00000000 N=0 00O00FF4:OO000504 s+4
A 4 = 0 0 0 0 0 0 0 0 A 5 = 0 0 0 0 0 0 0 0 A 6 = 0 0 0 0 0 0 0 0 A7=000O0FF0 Z=0 OOOOOFF8:00000502 s+8
D0=00000000 D1=00000000 D2=00000000 D3=00000000 V=0 0OOO0FFC:O00005O0 s+12
D4-00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001000:00000000 s+16
>MOVE.W (A0),D2

PC=000432 SR=2000 SS=00000FF0 US=00000000 X=0 OOOOOFFO:0000041A s


A0=00000500 Al=00000502 A2=00000000 A3=00000000 N=0 0000OFF4:00O0O5O4 S + 4
A4=00000000 A5=00000000 A6=00000000 A7=00000FF0 Z=0 00000FF8:00000502 S + 8
D0=00000000 D1=00000000 D2-=00000001 D3=00000000 V=0 OOOOOFFC:00000500 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001000:00000000 s+16
>MOVE.W (Al),D3

PO000434 SR=2000 SS=00000FF0 US=00000000 X=0 0OOOOFF0:0000041A s


A0=00000500 Al=00000502 A2=00000000 A3=00000000 N=0 OOOOOFF4:00000504 s+4
A4=00000000 A5=00000000 A6-00000000 A7=0O0OOFF0 Z=0 OOOOOFF8:00000502 S+8
D0=00000000 D1=00000000 D2=00000001 D3=000O0002 V=0 OOOOOFFC:00000500 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001000:00000000 s+16
>ADD.W D2,D3

PO0004 36 SR=2000 SS=00000FF0 US=00000000 X=0 OOOOOFF0:OOO0041A s


A0=00000500 Al=00000502 A2=00000000 A3=00000000 N=0 OOOOOFF4:00000504 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00000FF0 Z=0 00000FF8:00000502 s+8
D0=00000000 D1=00000000 D2=00000001 03=00000003 V=0 00000FFC:00000500 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001000:00000000 s+16
>MOVEA.L $04(SP),A3

PC=00043A SR=2000 SS=00000FF0 US=00000000 X=0 00000FF0:000004lA s


A0=00000500 Al=00000502 A2=00000000 A3=00000504 N=0 OOOOOFF4:00000504 s+4
A4=00000000 A5=00000000 A6=00000000 A7=0OOOOFFO Z=0 00000FF8:00000502 s+8
D0=00000000 D1=00000000 D2=00000001 D3=00000003 V=0 OOOOOFFC:00000500 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001000:00000000 s+16
>MOVE.W D3, (A3)

PC=00043C SR=2000 SS=O0OOOFF0 US=00000000 X=0 0O000FF0:OO00041A s


A0=00000500 Al=00000502 A2=00000000 A3=00000504 N=0 0O000FF4:00000504 s+4
A4=00000000 A5»00000000 A6=00000000 A7=O0000FF0 Z=0 O00OOFF8:00000502 s+8
D0=00000000 Dl=00000000 D2=00000001 D3=00000003 V=0 OOOOOFFC-.00000500 s+12
D4=0O000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001000:00000000 s+16
>RTS
280 Chapter 6 Assembly language programming

EOC0041A SR=2000 SS=00C0CFF4 OS=00000000 X=0 00000FF4:C0000504 s


A0=00000500 Al=00000502 A2=00000000 A3=00000504 N=0 000OOFF8:OO0005O2 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00000FF4 Z=0 00000FFC:00000500 s+8
D0=00000000 D1=00000000 D2=00000001 D3=00000003 V=0 00001000:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001004:00000000 s+16
>MOVE.W $05C4,D2

PC=000420 SR=2000 SS=00000FF4 US=OO000OOO X=0 00000FF4:00000504 s


A0=00000500 Al=00000502 A2=00000000 A3=00000504 N=0 OOOOOFF8:00000502 s+4
A4=00000000 A5=00000000 A6=00000000 A7=00000FF4 Z=0 OOOOOFFC:00000500 s+8
D0=00000000 D1=00000000 D2-00000003 D3=00000003 V=0 00001000:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001004:00000000 s+16
M.SA.L $OC(SP),SP

PO000424 SR=2000 3S=C0001000 US=00000000 X=0 00001000:00000000 s


A0=00000500 Al=00000502 A2=00000000 A3=00000504 N=0 00001004:00000000 S+4
A4=00000000 A5=00000000 A6=00000000 A7=00001000 Z=0 00001008:00000000 s+8
D0=00000000 D1=00000000 D2=00000003 D3=00000003 V=0 0000100C:00000000 s+12
D4=00000000 D5=00000000 D6=00000000 D7=00000000 C=0 00001010:00000000 s+16
>STOP #$2700

If we look at memory again, we will find that the sum of X implement a text matching algorithm that determines
and Y has been stored in location Z. whether a string contains a certain substring. The problem
can be solved by sliding the substring along
000500 00 01 00 02 00 03 00 00 00 00 00 00 00 00 00 00 the string until each character of the sub-
string matches with the corresponding
We have passed the parameters by reference. In practice, a character of the string, as illustrated in Fig. 6.33.
programmer would pass parameters that aren't changed in The string starts at address $002000 and is terminated by a
the subroutine by value, and only pass parameters that are to carriage return (ASCII code $0D). The substring is stored at
be changed by reference. location $002100 onwards and is also terminated by a car-
riage return. In what follows, the string of characters is
6.6 Examples of 68K programs referred to as STRING, and the substring as TEXT.
We now put together some of the things we've learned about We will construct a main program that calls a subroutine,
the 68K's instruction set and write a simple program to MATCH, to scan the string for the first occurrence of the

String T H I S T H A T T H E N T H E O T H E R
Substring T H E N THE

Step Matches T H I S T H A T T H E N T H E O T H E R

1 5 THE N T H E
2 0 T H E N T H E
3 0 T H E N T H E
T H
ui I

4 1 T H E N
5 0 T H E N T E
1—

6 6 T H E N H E
7 0 T H E N T H E
Z ul X 1—

8 0 T H E T H E
9 1 T H N T H E
10 0 T E N T H E
11 8 H E N T H E
12 0 T H E N T H E Figure 6.33 Matching a string
13 0 T H E N T H E and a substring.
6.6 Examples of 68K programs 281

substring. Because STRING and TEXT are both strings of con- in the string matching the first character of the substring. This
secutive characters, we will pass them to MATCH by reference. address is to be returned on the stack. If the match is unsuc-
The subroutine should return the address of the first character cessful, the null address, $00000000, is pushed on the stack.

CRET EQU $0D ASCII code for c a r r i a g e r e t u r n

ORG $400 S t a r t of the main program


LEA $1000,A7 Set up the stack pointer
PEA STRING Push the address of the s t r i n g
PEA TEXT Push the address of the s u b s t r i n g
LEA -4(A7) ,A7 Make room on the stack for the r e s u l t
BSR MATCH Perform the match
MOVE.L (A7)+,D0 L e t ' s have a look a t the r e s u l t
LEA 8(A7),A7 Clean up the stack (remove the 2 parameters)
STOP #$2700

MATCH matches the substring whose location is pointed at by


A0 with the string whose location is pointed at by Al.
Both strings are terminated by a carriage return.

The match is carried out by comparing the first character of


the substring with the characters of the string, one by one.
If a match is found, the rest of the characters of the
substring are matched with the corresponding characters of
the string. If they all match up to the substring terminator,
the search is successful. As soon as a mismatch is found, we
return to matching the first character of the substring with
a character from the string. If the terminator of the string
is reached, the search has been unsuccessful.

MATCH MOVEM.L D0/A0-A3,-(A7) Save all working registers


MOVEA.L 32(A7),A0 Get STRING address off the stack
MOVEA.L 28(A7),A1 Get TEXT (substring) address off the stack

NEXT MOVE.B (A0)+,DO Get a character from the string


CMP.B #CRET,D0 Is this character a carriage return?
BEQ FAIL If carriage return then no match so exit
CMP.B (A1),D0 Match character with char from substring
BNE NEXT If no match then move along the string

We have found the first match.


We have to save the two pointers before performing the
submatch in case we have to return to matching the pairs
of first characters.

MOVEA.L A0,A2 Save A0 in A2 in case of no full match


MOVEA.L A1,A3 Save Al in A3
ADDA.L #1,A1 Increment pointer to substring
*
LOOP MOVE.B (A1)+,D0 Get next character from substring
CMP.B #CRET,D0 If terminator found then success
BEQ SUCCESS
CMP.B (A0)+,DO Else compare it with next char from string
BEQ LOOP Repeat while they match

No submatch found so prepare to continue matching pairs


of first characters.

MOVEA.L A2,A0 Restore A0 and Al


MOVEA.L A3,A1 to their values before the submatch
BRA NEXT Try again

SUCCESS SUBA.L #1,A2 Undo work of auto increment


MOVE.L A2,24(A7) Push address of match on stack
BRA RETURN

FAIL MOVE.L f0,24(A7) Push null address on stack for fail


* MOVEM.L (A7)+,DO/A0-A3 Restore all working registers
RETURN RTS
ORG $002000 Location of the string
STRING DC.B 'THIS THAT THEN',$0D
ORG $002100 Location of substring to be matched
TEXT DC.B "THEN THE',$0D
END $400
282 Chapter 6 Assembly language programming

6.6.1 A circular buffer • If the buffer is empty, removing a new character results in the
contents of the lower byte of DO being set to zero and its most-
Many computers can't process data as they receive it; the significant bit set.
data is placed in a store until it's ready for use by the com- • Apart from DO, no other registers are to be modified by calling
puter. This store is a buffer and is analogous to a doctor's the subroutine.
waiting room. The number of people in the waiting room
The first step in solving the problem is to construct a dia-
increases as new patients enter and decreases as patients are
gram (Fig. 6.34) to help us visualize the buffer. Figure 6.34
treated by the doctor. Consider a 68K-based system with a
shows the memory map corresponding to the buffer. A region
software module that is employed by both input and output
of 1024 bytes ($400) is reserved for the buffer together with
routines, and whose function is to buffer data. When it's
two 32-bit pointers. INLptr points to the location of the next
called by the input routine, it adds a character to the buffer.
free position into which a new character is to be placed and
When it's called by the output routine, it removes a charac-
OUT_ptr points to the location of the next character to be
ter from the buffer. Below are the operational parameters of
removed from the buffer. At the right-hand side of the dia-
the subroutine.
gram is the logical arrangement of the circular buffer. This
• Register DO is to be used for character input and output. arrangement provides the programmer with a better mental
The character is an 8-bit value and occupies the lowest-order image of how the process is to operate.
byte of DO. The first level of abstraction in pseudocode is to determine
• Register Dl contains the code 0, 1, or 2 on entering the the overall action the module is to perform. This can be writ-
subroutine. ten as follows.
• Code 0 means clear the buffer and reset all pointers.
Module Circular_buffer
• Code 1 means place the character in DO into the buffer. Save working registers
• Code 2 means remove a character from the buffer and place it CASE OF:
in DO. Dl = 0: Initialize system
Dl = 1: Input a character
• We assume that a higher-level module ensures that only one of Dl = 2 : Output a character
0, 1, or 2 is passed to the module (i.e. invalid operation codes END_CASE
cannot occur). Restore working registers
End Circular_buffer
• The location of the first entry in the buffer is at $010000 and
the buffer size is 1024 bytes. Pointers and storage may be placed
At this, the highest level of abstraction, we have provided
after the end of the buffer.
no indication of how any action is to be carried out and the
• If the buffer is full, the addition of a new character overwrites only control structure is the selection of one of three possible
the oldest character in the buffer. In this case, bit 31 of DO is set
functions. The next step is to elaborate on some of these
to indicate overflow and cleared otherwise.
actions.

Direction of
pointer movement
Start 010000
\st a r t

1024-byte \ End
buffer

End0103FF
010400 !N_ptr
010404 OUTLptr 1
OUT_ptr IN_ptf
010408 Count

(a) Buffer memory map. (b) Logical arrangement of buffer.

Figure 6.34 The circular buffer.


6.6 Examptes of 68K programs 2 8 3

Module Circular_buffer
Save working registers
IF [Dl] = 0 THEN Initialize END_IF
IF [Dl] = 1 THEN Input_character E N D I F
IF [Dl] = 2 THEN Output_character END_IF
Restore working registers
End Circular_buffer

Initialize
Count = 0
IN_ptr = Start
OUT_ptr = Start
End Initialize

Input_character
Store new character
Deal with any overflow
End Input_character
Output_character
IF buffer NOT empty THEN Get_characterJrombuffer
ELSE return null character
END_IF
End Output__character

The pseudocode is now fairly detailed. Both the module ving character and the pointer to the output must be moved
selection and the initialization routines are complete. We still to reflect this.
have to work on the input and output routines because of the Sometimes it is helpful to draw a simplified picture of the
difficulty in dealing with the effects of overflow and under- system to enable you to walk through the design. Figure 6.35
flow in a circular buffer. shows a buffer with four locations. Initially, in state (a), the
We can determine the state of the buffer by means of a buffer is empty and both pointers point to the same location.
variable, Count, which indicates the number of characters in At state (b), a character is entered, the counter incremented,
the buffer. If Count is greater than zero and less than its max- and the input pointer moved to the next free position. States
imum value, a new character can be added or one removed (c) to (e) show the buffer successively filling up to its maxi-
without any difficulty. If Count is zero, the buffer is empty mum count of 4. If another character is now input, as in state
and we can add a character but not remove one. If Count is (f), the oldest character in the buffer is overwritten.
equal to its maximum value and therefore the buffer is full, It is not necessary to rewrite the entire module in pseudocode.
each new character must overwrite the oldest character as We will concentrate on the input and output routines and then
specified by the program requirements. This last step is tricky begin assembly language coding. Because the logical buffer is cir-
because the next character to be output (the oldest character cular while the physical buffer is not, we must wrap the physical
in the buffer) is overwritten by the latest character. Therefore, buffer round. That is, when the last location in the physical
the next character to be output will now be the oldest survi- buffer isfilled,we must move back to the start of the buffer.

Input_character
Store new c h a r a c t e r a t IN_ptr
IN_ptr = IN_ptr + 1
IF IN_ptr > End THEN IN_ptr = S t a r t END_IF
IF Count < Max THEN Count = Count + 1
ELSE
Set overflow flag
OOT_ptr = OUT_ptr + 1
IF OUT_ptr > End THEN OOT_ptr = S t a r t END_IF
END_IF
End Input_character

Output_character
IF Count = 0 THEN r e t u r n n u l l and s e t underflow flag
ELSE
Count = Count - 1
Get c h a r a c t e r pointed a t by OUT_ptr
OUT_ptr = OOT_ptr + 1
IF OUT_ptr > End THEN OUT_ptr = S t a r t END_IF
END_IF
End Output_character
284 Chapter 6 Assembly language programming

V 1 2 /

out J t" 1 out I


in out_J in
in
(a) Count = 0 (b) Count = 1 (c) Count = 2

y. 4
3 \
\
f 3 \ / 4 3 \

i 2 J
V Y 5 2 /

A A
out_J out_J out I
in in in
Figure 6.35 Operation of the
(d) Count = 3 (e) Count = 4 (f) Count circular buffer.
The program design language has now done its job and we
can translate the routines into the appropriate assembly
language.

CIRC EQU * This module implements a circular buffer


MOVEM.L A0-A1,-(SP) Save working registers
BCLR.L #31,DO Clear bit 31 of DO (no error)
CMPI.B #0,D1 Test for initialize request
BNE.S CIRC1 IF not 0 THEN next test
BSR.S INITIAL IF 0 THEN perform initialize
BRA.S CIRC3 and exit
CIRC1 CMPI.B #1,D1 Test for input request
BNE.S CIRC2 IF not input THEN must be output
BSR.S INPUT IF 1 THEN INPUT
BRA.S CIRC3 and exit
CIRC2 BSR.S OUTPUT By default OUTPUT
CIRC3 MOVEM.L (SP)+,A0-A1 Restore working registers
RTS End CIRCULAR
*
INITIAL EQU * This module sets u the circular buffer
CLR.W COUNT Initialize counter and pointers
MOVE.L •BUFFER,IN PTR Set up IN_ptr
MOVE.L #BUFFER,OOT_PTR Set up OUT_ptr
RTS
*
INPUT EQU * This module stores a character in the buffer
MOVEA.L IN PTR,A0 Get pointer to input
MOVE.B DO,(A0)+ Store char in buffer, update pointer
CMPA.L #END+1,A0 Test for wrap-round
BNE.S INPUT1 IF not end THEN skip reposition
MOVEA.L #START,AO Reposition input pointer
INPUT1 MOVE.L A0,IN_PTR Save updated pointer
CMPI.W #MAX,COUNT Is buffer full?
BEQ.S INPUT2 IF full THEN deal with overflow
ADDQ.B #l,COOHT ELSE increment character count
RTS and return
INP0T2 BSET.L #31,DO Set overflow flag
MOVEA.L OUT PTR.AO Get output pointer
LEA 1(A0),A0 Increment OUT_ptr
CMPA. L #END+1,A0 Test for wrap-round
6.6 Examples of 68K programs 285

BNE.S INPUT3 IF not wrap-round THEN skip fix


MOVEA.L #START, AO ELSE wrap-round OUT_ptr
INPUT3 MOVE.L A0,OUT_PTR Update OUT_ptr in memory
RTS and return
OUTPUT TST.W COUNT Examine state of buffer
BNE.S OUTPUT1 IF buffer not empty output char
CLR.B DO ELSE return null output
BSET.L #31,DO set underflow flag
RTS and exit
OUTPUT1 S U B I . W #1,COUNT Decrement COUNT for removal
MOVEA.L OUT P T R , A 0 Point to next char to be output
MOVE.B (A0)+,D0 Get character and update pointer
CMPA.L #END+l,AO Test for wrap-round
BNE.S OUTPUT2 IF not wrap-round THEN exit
MOVEA.L #START,AO ELSE wrap-round OUT_ptr
OUTPUT2 MOVE.L A 0 , O U T PTR Restore OUT_ptr in memory
RTS

Now that we've designed and coded the buffer, the next example, to initialize the buffer you type OX, where X is any
step is to test it. The following code is the assembled circular character. If you type 1Y, the character Y is stored in the next
buffer program with the necessary driver routines. The pro- free place in the buffer. If you type 2Z, the next character to be
gram inputs two characters at a time, and implements an output is displayed. After each operation, the contents of the
8-byte buffer. The first character of a pair is the control char- buffer are printed and the current value of the variable count
acter (i.e. 0 = initialize, 1 = input, and 2 = output). For displayed.

1 00000400 ORG $400


2 00000400 4DF900001012 LEA HEADER, A6 ;Print heading
3 00000406 6100015E BSR PRINT
4 0000040A 61000104 NEXT: BSR GETCHAR REPEAT
5 0000040E 04010030 SUB.B • #530,Dl Get number (0, 1, or 2)
6 00000412 1E01 MOVE.B D1,D7 Save it
7 00000414 610000FA BSR GETCHAR Get character for input routine
8 00000418 1001 MOVE.B D1,D0
9 0000041A 1207 MOVE.B D7,D1 Restore number
10 0000041C 6100002A BSR CIRC Call the buffer routine
11 00000420 OC010002 CMP.B #2,D1 IF we did output THEN print the char
12 00000424 66000018 BNE CONT
13 00000428 1C00 MOVE.B D0,D6 ;Save character from output
14 0000042A 610000F4 BSR NEWLINE
15 0000042E 4DF900001023 LEA OUT.A6 ;Print "output"
16 00000434 61000130 BSR PRINT
17 00000438 1206 MOVE.B D6,D1
18 0000043A 610000DC BSR PUTCHAR ;Now print the character
19 0000043E 610000EO CONT: BSR NEWLINE
20 00000442 610000E8 BSR DISPLAY ;Display the buffer contents
21 00000446 60C2 BRA NEXT ;FOREVER
22
23 00000448
*
CIRC: EQU ;Implement a circular buffer
24 00000448 48E700C0 MOVEM.L
*
A0-A1,-(SP) ;Save working registers
25 0000044C 0880001F BCLR #31,DO ;Clear bit 31 of DO (no error)
26 00000450 0C010000 CMPI.B »0,D1 ;Test for initialize request
27 00000454 6604 BNE.S CIRC1 ;IF not 0 THEN next test
28 00000456 6114 BSR.S INITIAL ;IF 0 THEN perform initialize
29 00000458 600C BRA.S CIRC3 ;and exit
30 0000045A 0C010001 CIRC1: CMPI.B #1,D1 ;Test for input request
31 0000045E 6604 BNE.S CIRC2 ;IF not input THEN must be output
32 00000460 6126 BSR.S INPUT ;IF 1 THEN INPUT
33 00000462 6002 BRA.S CIRC3 ;and exit
34 00000464 6174 CIRC2: BSR.S OUTPUT ;By default OUTPUT
35 00000466 4CDF0300 CIRC3: MOVEM.L (SP)+,A0-A1 ;Restore working registers
36 0000046A 4E75 RTS ;End CIRCULAR
37
38 0000046C INITIAL: EQU * ;Set up the circular buffer
39 0000046C 427900001008 CLR.W COUNT ;Initialize counter and pointers
40 00000472 23FC00001000 MOVE.L •BUFFER,IN_POINT ;Set up IN_ptr
0000100A
41 0000047C 23FC00001000 MOVE.L •BUFFER,OUT_POIN ;Set up OUT_ptr
0000100E
42 0 0 0 0 0 4 8 6 4E75 RTS
43
44 00000488
*
INPUT: EQU ;Store a char in the buffer
45 00000488 20790000100A MOVEA. L
*
IN POINT,A0 ;Get pointer to input
46 0000048E 10C0 MOVE.B DO,(A0)+ ;Store char in buffer, update ptr
47 00000490 B1FC00001008 CMPA.L #LAST+1,A0 ;Test for wrap-round
48 00000496 6606 BNE.S INPUT1 ;IF not end THEN skip reposition
286 Chapter 6 Assembly language programming

49 00000498 207C00001000 MOVEA.L •START,A0 Reposition input pointer


50 0000049E 23C80000100A INPUT1: MOVE.L A0, IN POINT Save updated pointer
51 000004A4 OC7900080000 CMPI.W #MAX,COUNT Is buffer full?
1008
52 000004AC 6708 BEQ.S INPUT2 IF full THEN deal with overflow
53 000004AE 527900001008 ADDQ.W #1,COUNT ELSE increment character count
54 000004B4 4E75 RTS and return
55 000004B6 08C0001F INPUT2: BSET #31,DO Set overflow flag
56 000004BA 20790000100E MOVEA.L OUT POINT, A0 Get output pointer
57 000004C0 41E80001 LEA 1(A0),A0 Increment OUT ptr
58 000004C4 B1FC00001008 CMPA.L #LAST+1,A0 Test for wrap-round
59 000004CA 6606 BNE.S INPUT3 IF not wrap-round THEN skip fix
60 000004CC 207C00001000 MOVEA.L • START, A0 ELSE wrap-round OUT ptr
61 000004D2 23C80000100E INPUT3: MOVE.L A0,OUT_POINT Update OUT ptr in memory
62 000004D8 4E75 RTS and return
63
64 000004DA 4A7900001008 OUTPUT: TST.W COUNT Examine state of buffer
65 000004E0 6608 BNE.S OUTPUT1 IF buffer not empty output char
66 000004E2 4200 CLR.B DO ELSE return null output
67 000004E4 08C0001F BSET #31, DO set underflow flag
68 000004E8 4E75 RTS and exit
69 000004EA 047900010000 GUTPUT1: SUBI.W #1,COUNT Decrement COUNT for removal
1008
70 000004F2 20790000100E MOVEA.L OUT POINT,A0 Point to next char to be output
71 000004F8 1018 MOVE.B (A0)+,D0 Get character and update pointer
72 000004FA B1FC00001008 CMPA. L #LAST+1,A0 Test for wrap-round
73 00000500 6606 BNE.S OUTPUT2 IF not wrap-round THEN exit
74 00000502 207C00001000 MOVEA.L •START,A0 ELSE wrap-round OUT_ptr
75 00000508 23C80000100E OUTPUT2: MOVE.L A0,OUT_POINT Restore OUT ptr in memory
76 0000050E 4E75 RTS
77
78 00000510 103C0005 GETCHAR: MOVE.B #5,DO Read an ASCII character into Dl
79 00000514 4E4F TRAP #15
80 00000516 4E75 RTS
81 00000518 103C0006 PUTCHAR: MOVE.B #6,DO Print the ASCII character in Dl
82 0000051C 4E4F TRAP #15
83 0000051E 4E75 RTS
84 00000520 123C000D NEWLINE: MOVE.B #$0D, Dl New Line
85 00000524 61F2 BSR PUTCHAR
86 00000526 123C000A MOVE.B #$0A,D1
87 0000052A 60EC BRA PUTCHAR
88 0000052C 48E7FFFE DISPLAY: MOVEM.L A0-A6/D0-D7,-(A7) Display the buffer contents
89 00000530 61EE BSR NEWLINE
90 00000532 43F900001000 LEA BUFFER,Al
91 00000538 3E3C0007 MOVE.W #7,D7
92 0000053C 1219 DIS1: MOVE.B (A1)+,D1
93 0000053E 61D8 BSR PUTCHAR •Print a character
94 00000540 123C0020 MOVE.B #$20,Dl and a space
95 00000544 51CFFFF6 DBRA D7,DIS1
96 00000548 4DF900001037 LEA COUNTER,A6 Print header before current count
97 0000054E 61000016 BSR PRINT
98 00000552 323900001008 MOVE.W COUNT,Dl Display count
99 O00O0S58 06010030 ADD.B #$30,Dl
100 0000055C 61BA BSR PUTCHAR
101 0000055E 61C0 BSR NEWLINE
102 00000560 4CDF7FFF MOVEM.L (A7)+,A0-A6/D0-D7
103 00000564 4E75 RTS
104 *
105 00000566 48E7FFFC PRINT: MOVEM. L A0-A5/D0-D7,-(A7) Print the string pointed at by A6
106 0000056A 121E PRINT1: MOVE.B (A6) +,D1
107 0000056C 6700000A BEQ PRINT2
108 00000570 103C0006 MOVE.B #6,DO
109 00000574 4E4F TRAP #15
110 00000576 60F2 BRA PRINT1
111 00000578 4CDF3FFF PRINT2: MOVEM.L (A7)+,A0-A5/D0-D7
112 0000057C 4E75 RTS
113
114
* ORG $1000
00001000
115 00001000 START: EQU *
116 00001007 LAST: EQU *+7
117 00000008 MAX: EQU 8
118 00001000 00000008 BUFFER: DS.B 8
119 00001008 00000002 COUNT: DS.W 1
120 0000100A 00000004 I N P O I N T : DS.L 1
121 0000100E 00000004 OUT POINT : DS.L 1
122 00001012 43697263756C HEADER: DC.B 'Circular Buffer ' 0
617220427566
6665722000
123 00001023 436861726163 OUT: DC.B 'Character output = \0
746572206F75
74707574203D
2000
1
124 00001037 2020436F756E COUNTER: DC.B Count = \0
74203D2000
125 00000400 END $400
6.6 Examples of 68K programs 287

This example concludes our overview of 68K assembly the assembly language syntax of the 68K instruction into the
language programming. We have only touched the surface of RTL notation that defines the action of the instruction.
this topic. Real assemblers are far more complex and include (a) MOVE 3000,4000 (g) MOVE (A0),D3
facilities to design large programs such as the separate com- (b) MOVE D0,D4 (h) MOVE #12,(A0)
pilation of modules. However, our intention was never to cre- (c) MOVE 3000,DO (i) MOVE (Al),(A2)
ate an assembly language programmer; it was to give you (d) MOVE DO,3000 (j) ADD D2,D1
some insight into how machine-level instructions are used to (e) MOVE #4000,D4 (k) ADD #13,D4
achieve high-level actions. (f) MOVE #4000,5000 (I) ADD (A3),1234

6.2 Explain why the following assembly language and RTL


constructs are incorrect.
SUMMARY
(a) MOVE D3 , #4 (d) [D3] <- A0 +
In this chapter we've looked at how you can use a
(b) MOVE [D3] ,D2 (e) [D3] <- #3
microprocessor's instruction set to write simple
(c) MOVE (D3) ,D2 (f) 3 <- [D3]
programs.
This is not an assembly language programming text and we
cannot delve deeply into assembly language programming. We 6.3 Create a simple 68K program called ADDER. Your program
have, however, demonstrated that the assembly language should add together the numbers 6,4,12,16,17, and 50. The
programmer has to appreciate the programming environment program is to be assembled with the 68K cross-assembler and
that requires the use of assembly directives to allocate memory then run on the 68K simulator (either Easy68K or the Teesside
space for variables and constants. assembler/simulator). Run the binary file you have created in
the simulation mode.
We have examined some of the 68K's instructions and
demonstrated how to write a program. More importantly, we
have looked at the addressing modes supported by the 68K and 6.4 Give examples of valid 68K assembly language instructions
shown how data structures like lists, tables, and arrays can be that use
accessed. (a) register-to-register (c) memory-to-register
Finally, we have introduced the stack used by the 68K to keep addressing addressing
track of subroutine return addresses and have demonstrated (b) register-to-memory (d) memory-to-memory
how the stack can be used to pass parameters to and from a addressing addressing
subroutine.

6.5 The following 68K assembly language program illustrates


what an assembler does and is designed only to illustrate some
« PROBLEMS points. The source program is followed by its assembled listing.
6.1 Describe the action of the following 68K assembly language Examine both the source code and listing file, and try to follow
instructions in RTL (register transfer language). That is, translate what is happening.

ORG $400
Test EQU 6 Dummy equates
Alan EQU 7
XXX DS.W 2 Save two words of storage
YYY DC.L $12345678 Put the longword $12345678 in memory
Name DC.B 'Clements Put an ASCII string in memory
DC.B $FF
DC.L Test+Name Store a 32-bit constant
DC.B 4 Put 4 in memory
MOVE.L #Name,A0
Next MOVE.B (A0)+,D0 Pick up a character
CMP.B #$FF,D0 Test for end of string
BEQ Exit And exit on terminator
BSR Print Print a character
BRA Next Repeat
Exit STOP #$2700 Halt the 68K
*
Print NOP Dummy subroutine
NOP
RTS Return

END $400 END needed ($400 is start address)


288 Chapter 6 Assembly language programming

The following code was produced by a 68K cross-assembler (c) What is the effect of the assembler directive DC . w 12 34?
from the above source code. (d) What is the effect of the assembler directive DC. w $1234?

1 00001000 ORG $400


2 00000006 TEST: EQU 6 ;Dummy equates
3 00000007 ALAN: EQU 7
4 00001000 00000004 XXX: DS.W 2 ;Save two words of storage
5 00001004 12345678 YYY: DC.L $12345678 ;Put longword $12345678 in memory
6 00001008 436C656D656E NAME: DC.B 'Clements' ;Put an ASCII string in memory
7473
7 00001010 FF DC.B $FF
8 00001012 0000100E DC.L TEST+NAME /Store a 32-bit constant
9 00001016 04 DC.B 4 ;Put 4 in memory
10 00001018 207C00001008 MOVE.L #NAME,A0
11 0000101E 1018 NEXT: MOVE.B (A0)+,D0 /Pick up a character
12 00001020 0C0000FF CMP.B #$FF,DO /Test for end of string
13 00001024 67000008 BEQ EXIT /And exit on terminator
14 00001028 61000008 BSR PRINT /Print a character
15 0000102C 60FO BRA NEXT /Repeat
16 0000102E 4E722700 EXIT: STOP #$2700 /Halt the 68K
17
18 00001032 4E71 PRINT: NOP /Dummy subroutine
19 00001034 4E71 NOP
20 00001036 4E75 RTS /Return
21
22 00000400 END $400 /END needed

6.6 By means of a memory map explain the effect of the (e) What is the effect of t h e ' + ' in the effective address
following sequence of 68K assembly language directives. (A0)+?
(f) What is the effect of the' - ' in the effective
ORG $600
DS.L 2 address - ( A 0 ) ?
DC.L 2 (g) W h y ' A D D A . L #4, A0',but'ADD.L#4,D0'?
DC.B '1234'
Time DC.B 6 6.10 What is wrong with the following fragment of 68K assem-
Top DS.B 6 bly language (the error is one of semantics)?
BScl EQU 2
ITl EQU 3 CMP.W #4,Q IF Q = 4 THEN X = 5 ELSE X = Y
SE1 DS.B ITl+BScl BNE ELSE IF Q 4 THEN goto 'ELSE'
THEN MOVE.W #5,X IF Q = 4 THEN X = 5
ELSE MOVE.W Y,X ELSE part (i.e. X = Y)
6.7 What would the following 68K assembly Leave the program
EXIT
language fragment store at address $1002?
6.11 Translate the following fragment of high-level language
ORG $1000
p EQU 5 into 68K assembly language.
Q DS.B 2 IF T = 5
One DC.W P+Q THEN X = 4
END_IF
6.8 What is wrong with each of the following 68K assembly
language operations? Assume that T and X are in memory. Write a program to imple-
ment this fragment of code and run it on the 68K simulator.
a MOVE Temp,#4
Select your own values for variables T and X. Use the simulator's
(b)ADD.B #1,A3
trace mode to observe the behavior of the program.
CMP.L DO,#9
(c)
MOVE.B #500,D5 6.12 Translate the following fragment of high-level language into
(d)DS.B 1,2 68K assembly language. Use a 68K simulator to test your program.
(e)ADD.W +(A2),D3
(0 ORG #400 IF T = 5
THEN X = 4
& BEQ.B Loop 3
ELSE Y = 6
6.9 Answer the following questions about 68K assembler END_IF
conventions.
6.13 The 68K can operate with byte, word, and longword
(a) What is the effect of the assembler directive ORG $400? operands. What does this mean? Which type of operand do you
(b) What is the effect of the assembler directive DS. W 20? use in any particular circumstance?
6.6 Examples of 68K programs 289

6.14 Explain what the following 68K program does. Use the 68K
simulator to test your observations.
MOVE.B #20,DO
Again MOVEA.L #$1000 AO
CLR.B (AO)
ADDA.L #1,A0
SUB.B #1,D0
BNE Again
6.15 A sequence, or string of 1-byte ASCII characters is stored
at memory location $600 onward. A second sequence of equal
length is stored at memory location $700 onward. Each
sequence ends with the character $0D (i.e. the ASCII value for a
carriage return). Write a 68K assembly language program to
determine whether or not these two strings are identical. If they
are identical, place the value $00 in data register DO. If they are
not, place the value $FF in DO.
Use the 68K cross-assembler and simulator to write the
program and test it.
Modify your program to use the simulator's character input
routine to input the two strings into memory. The simulator's
character input code that puts a byte into D1 is

Get char MOVE.B #5,DO


TRAP #15
6.16 A sequence of ASCII-encoded characters is stored at mem-
ory location $600 onwards and is terminated by a $0D. Write a
program to reverse the order of the sequence (i.e. the first value
at location $600 will now be SOD, which was the old end of the
string).
Use the 68K simulator to input a string and print it in reverse
order.
The simulator's character output code that prints the byte in
D1is

Put char MOVE.B #6, DO


TRAP #15
6.17 The following program contains both syntax and semantic
errors. What is the difference between these two types of error?
Locate both types of error.

* This is a program to designed locate the smallest number in a table

ORG #400
Numbers DS.B 42,3,060,20,8,9,$A,$C,7,2,$F,5AF,8,600,0A,9,4 0,6,#FF
MOVE.B #Numbers,A0 AO points to table of numbers
CLR.B DO Current smallest number
N_2 MOVE.B (A0),D1 Get a number
ADD.B #1,A1 Point to next number
CMP.B D0,D1 Is new number lower?
BGE N_l
MOVE . B Dl, DO Keep new low number
N_l CMP.B D1,#$FF Check for end
BNE N_2
BRA Print Print it
END $400

Print MOVE.B #5,D1


TRAP #15
RTS
STOP #$2700
290 Chapter 6 Assembly language programming

6.18 Examine the following fragment of pseudocode and its 6.22 Write a subroutine to carry out the operation X*(Y+Z),
translation into 68K assembly language. Work through this codewhere X,Y, and Z are all wordlength (i.e. 16-bit) values.The three
and ensure that you understand it. Is the program correct? Canparameters, X, Y, and Z, are to be passed on the stack to the
you improve it? procedure.The subroutine is to return the result of the
calculation via the stack. Remember
X = 5 that the 68K instruction MULU
Y = 7 DO, D l multiplies the 16-bit
FOR 1= 1 TO 9 unsigned integer in DO by the 16-bit
Y == Y + I
unsigned integer in D1 and puts the
IF T(I) = J(I) f X THEN J(I) = T(I) * 4 - Y
32-bit product in D l .
ELSE J(I) = J ( D - T(I)
END_FOR Write a subroutine, call it, and
pass parameters X, Y, and Z on the
ORG $400 stack. Test your program by using
MOVEA #T,A0 A0 points at base of array T the 68K simulator's debugging
MOVEA #J,A1 Al points at base of array J facilities.
MOVE #1,D0 Use DO as a counter to hold '.
MOVE #5,D1 X = 5; Dl is X
MOVE #7,D2 Y = 7; • D2 is Y 6.23 Write a subroutine ADDABC
Next ADD D0,D2 Y = Y + I that performs the operation
MOVE (A0) ,D3 Read T(I) into D3 C = A + B. Variables A, B, and C are
MOVE (Al),D4 Read J (I) into D4 all word (i.e. 16-bit) values.Test your
MOVE D4,D5 D5 is a temp copy of J(I) program on the 68K simulator.
ADD D1,D5 Compute J(I) + X in D5
Your calling code and subroutine
CMP D5,D3 IF T(I) = J(I) + X
should have the following
BNE Else
MOLU #4,D3 THEN compute T(I) * 4 - Y features.
SUB D2,D3 • Parameters A and B should be
MOVE D3,(Al) J(I) = T(I) * 4 - Y passed on the stack to the
BRA End Loop
procedure by reference (i.e. by
Else SUB D3, D4 J(I) = J(I) - T(I)
address).
MOVE D4,(Al)
End >op ADDA #2,A0 Point to ]lext element in T • Because parameters A and Bare
ADDA #2,A1 Point to next element in J adjacent in memory, you need pass
ADD #1,D0 Increment the loop counter only the address of parameter A to
CMP #10,DO Repeat until I = 10
the subroutine (because the
BNE Next
address of parameter B is 2 bytes
6.19 Write a 68K program to run on the simulator, which on from parameter A).

• inputs a single ASCII-encoded numeric character Parameter C should be passed back to the calling program on
• converts the character into binary numeric form the stack by value.
• inputs and converts a second character Before you call the subroutine, make room on the stack for the
• adds the two numbers returned parameter (i.e. parameter C).
• converts the numeric result into character form After calling the subroutine, read the parameter off the stack
• prints the result as ASCII characters. into data register DO (i.e. DO should end up containing the
If the input characters are 5 and 7, the displayed result value of A+B).
should be 12. The subroutine ADDABC must not corrupt any registers.
Save all working registers on the stack on entry to the
6.20 Write a program to arrange a sequence of eight numbers
subroutine and restore them before returning from the
in descending order. You can store the numbers in memory
subroutine.
before the program is executed by means of the DC. B assem-
bler directive. For example When you write your code, preset the stack pointer to a
value like $1500 (by using either MOVEA . L #$1500, A7
List DC.B 1 , 2 , 5 , 4 , 8 , 5 , 4 , 2 or LEA $1500, A7). Doing this will make it easier to follow
There are many ways of performing this sorting operation. One the movement of the stack while your program is
of the simplest is to search the list for the largest number and running.
put it at the top of the list, then do the same to the remaining Make certain that you are operating with the correct operand
numbers, and so on. Use the 68K simulator to test your sizes! Use .w for data values and . L for addresses/pointers.
program. Some of the important instructions you might need are
6.21 Why is it best to pass parameters to and from a subrou- provided below. Make sure you understand exactly what they
tine by means of the stack? do.
6.6 Examples of 68K programs 291

MOVEM.L RegList,-(A7) Push a group of registers on stack


MOVEM.L (A7)+,RegList Pull a group of registers off stack
LEA X(Ai),Aj Load Aj with the contents of register Ai + X
MOVEA.L (Ai),Aj Load Aj with longword pointed at by Ai

Your program should be of the general form

ORG $400
LEA $1500,A7 Set up the stack pointer with an easy value
Pass the parameters
BSR ADDABC Call the subroutine
Get the result, C, in DO
Clean up the stack
STOP #$2700 Halt execution

ADD?iBC ...

RTS

ORG $1200 Put the test data here


A DC.W $1234 This is the first parameter
B DC.W $ABAB This is the second parameter
END $400

This is not an easy or trivial problem. You will need to draw a (b) What code would you use to clean up the stack?
map of the stack at every stage and take very great care not to (c) Draw a memory map of the stack immediately before exe-
confuse pointers (addresses) and actual parameters. cuting the RTS in the subroutine PQR.

6.24 Suppose you wish to pre-load memory with the value 6.28 Write an assembly language program to reverse the bits
1234 before executing a program. Which of the following opera- of a byte.
tions is correct? 6.29 Explain why the following assembly language and RTL
(a) DC.B #1234 constructs are incorrect
(b) DC.W 1234 (a) MOVE D4, #$64
(c) DC.W #1234 (b) MOVE (D3) ,D2
(d) DS.B $1234 (c) [D3] <- A0 + 3
(e MOVE.W #1234,Location (d) [D3] <- # 3
6.25 Which of the following defines MOVE. B (A2)+,D3? 6.30 The 68K has both signed and unsigned conditional
(a) D3 <r- [[A2]]; [A2] <r- [A2] + 1 branches. What does this statement mean?
(b) [D3] <r- [[A2]]; [A2] ^ [A2 ] + 1
6.31 You cannot (should not?) exit a subroutine by jumping out
(c) D3] <- [[A2]]; [A2] <- [A2] + 1
of it by means of a branch instruction. You must exit it with an
(d) [A2] <- [A2] + 1 ; [D3] <- [A2];
RTS instruction.Why?
6.26 Which of the following statements is true when a parameter
6.32 Assume that a string of ASCII characters is located in
is passed to a subroutine by reference (i.e. not by value).
memory starting at location $2000. The string ends with the
(a) The parameter can be put in an address register. character 'Z'. Design and write a 68K assembly language pro-
(b) The address of the parameter can be put in an address gram to count the number of 'E's, if any, in the string.
register.
(c) The address of the parameter can be pushed on the stack. 6.33 Express the following sequence of 68K assembly language
(d) The parameter can be pushed on the stack. instructions in register transfer language and explain in plain
(e) Parts (a) and (d) are correct. English what each instruction does.
(f) Parts (b) and (c) are correct. (a) LEA 4(A2) ,A1
(b) MOVEA.L A3,A2
6.27 Consider the following code:
(c) MOVE.B (AI) ,D3
MOVE.W X , - ( A 7 ) Push X (d) MOVE.B #5, (Al)
MOVE.L Y , - ( A 7 ) Push Y (e) BCS ABC
BSR PQR C a l l PQR (f) MOVE.B (Al)+,-(A3)
Clean__up C l e a n up t h e stack
6.34 The following fragment of 68K assembly language has
(a) Why do you have to clean up the stack after returning from
several serious errors. Explain what the errors are. Explain how
the subroutine?
you would correct the errors.
292 Chapter 6 Assembly language programming

MOVE.B X,D0 Get X in a data register


CMP.B #4,DO IF X = 4 THEN X = X + 6
BEQ Add_6
MOVE.B D0,X Restore X in memory
PEA X Push X on the stack
BSR Sqr Calculate X2
X DS.W 1 Save space for X
STOP #$2700
*
ADD 6. ADD.B #6,DO X = X + 6
RTS Return
Sqr MOVE.L (A7)+,D2 Get X
MULU D2,D2 Square X
MOVE.L D2,-(A7) Put X*X on the stack
RTS Return

6.35 Suppose you are given an algorithm and asked to design 6.37 Suppose that A0 contains $F12CE600.What is the result
and test a program written in 68K assembly language. How of
would you carry out this activity? Your answer should include (a) ADDA.L #$1234, A0
considerations of program design and testing, and the necessary (b) ADDA.W #$1234,A0
software tools. (c) ADDA.W #$4321,A0
6.36 Suppose that DO contains SF12C4689 and D1 contains 6.38 What is the effect of the following code?
$21 IDOFFI.What is the result of
CLR DO
(a) ADD.B D 0 . D 1 MOVE.B D0,D1
(b) ADD.W D 0 , D 1 MOVE.B #10,D2
(c) ADD.L D 0 , D 1 XXX ADD.B D2,D0
In each case, give the contents of D1 after the operation and ADD.B #1,D1
the values of the C, Z, N, and V flags. ADD.B D1,D0
SUB.B #1,D2
BNE XXX
STOP #$2700

You might also like