CSC218 Sequential Programming Note
CSC218 Sequential Programming Note
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.
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.
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
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
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.
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
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.
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
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.
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).
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.
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.
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.
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:
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).
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.
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.
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.
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
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
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?
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
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.
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
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
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.
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
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
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.
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.
•-< *~*
Memory
R2 I
R3
R4 [
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.
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.
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
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 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.
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
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
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
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
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
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.
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
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 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
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
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.
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^
Symbol-name Value
P 2000
Q 2002
Address in memory
R 2004
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
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
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
Symbol-name Value
BUFFER 500
DOME 424
GET CHAR 428
<l I
J
2i.
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)
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
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.
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.
*~ ( I ~1 " | I
—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,;,:-,]
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
AO
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
Before Before
A2 D4
D3
After SWAP D4
AfterEXG A2,D3
A2
D3
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
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)
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.
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
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
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
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).
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
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 .
FOR K = I TO J
ENDFOR
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
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
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
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
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.
Body of loop
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
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
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
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
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
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.
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.
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.
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.
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?
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.
DO
X X Offset
The offset selects an Data block 3
AO A1
item within a data Mock.
D1
Y
SUNDAY EQU 0
MONDAY EQU 1
TUESDAY EQU 2
WEDNESDAY EQU 3
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.
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
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 $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.
- - ^ ^ i
^—•001000 K^FROM
•./•; AC
001010 *TO
^ \ A 1 ...'••'.
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
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
D
B C C C--D
SP SP B SP SP r*
fSP-1] — •
im A (SP] | — ¥ A+B ISP—11 H A+B
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
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
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.
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 $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.
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.
This is the character entered from the keyboard and captured by the TRAP #15.
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.
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.
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.
And so on ..
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.
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
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
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
(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
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
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.
_ Memory
x osoo
0500
Y 0502
Z 0504
Stack Stack
_Stack Stack
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.
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.
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.
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
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 /
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.
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.
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
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
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?
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
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
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
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
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
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