Introduction to Assembly Language
By the way, "CPU" stands for "Central
Processing Unit", which is just a fancy term for the computer
A Special Note:
A knowledge of Digital Circuitry is a very important asset
to understanding the depths of CPU Architecture as it relates
to Assembly Language, because as it will be explained later,
the CPU Architecture is composed of Digital Circuitry, and all
Assembly Language is solidly based on understanding that Architecture.
It is this direct link that may cause problems when attempts
are made to pursue the knowledge and understanding of Assembly
Language for any CPU. This turns out to be quite reasonable,
in that the manner in which a CPU decodes its instructions is
by a collection of Gates, Flip-Flops, Data-Latches, Counters,
and Timers. More about this will be explained later.
A Second Special Note:
It has been my experience in teaching these concepts over
the years, is that if we can first understand how a CPU accesses
memory with the many different "Addressing Modes",
the rest will come a lot easier. I firmly believe that this is
the heart and core of where we need to concentrate.
Group #1 - Introduction
Group #2 - 256 Possible
Group #3 - Simplest possible
Group #4 - Some basic
Assembly Language Commands
Group #5 - Certain Scenarios
Group #6 - Some actual
CPU codes vs Binary Architecture
Group #7 - Easy way to
do Hexadecimal Codes
Often as not, when the average individual tries to learn Assembly
Language, it seems at first like some kind of an impossible task.
This is especially so if you don't have any help, or perhaps
the right kind of help. I will make a bold statement ... There
are ways to approach this subject that can really make a difference,
whether it is when you are learning this by yourself, or in the
classroom. I'm going to also make another bold statement, I think
that far too much time and emphasis is placed on primitive binary
structure at the beginning. I will say that binary code is at
the core of all that we will discuss, but much of what we will
need can be learned as we go. Then, I will appear to contradict
myself right off the bat. However, we will soon see that this
might not be such a contradiction after all.
First, the contradiction:
- In binary code there is a simple premise, in that every time
you add one binary bit to the combination, the possibilities
double. I.e. with 2 binary bit positions there are 4
possibilities (00,01,10,11), and with 3 binary bit positions
there are 8 possibilities, and with 4 binary positions there
are 16 possibilities.
- Now it doesn't take a mathematician to continue this out
to even more positions and possibilities, but let's bypass this
for a while so that we can get down to the meat of our subject.
Now, consider what we have just
said, where 8 binary bits would allow 256 possible configurations:
- If we need a binary computer to do various operations, an
8-bit configuration would allow us to contrive 256 different
instructions. We might be able to do a considerable number of
things with 256 instructions, although at the beginning it might
be a little difficult to imagine that we would need this many.
- To begin with, let's reiterate something about computers
from the simplest to the most complex:
A computer only does 2 things: It either moves data, or manipulates
data (some say "mangles data").
- Considering this to be actually true, then what is the value
of so many possible instructions?
- Well, the point is that if we are going to have the computer
move some data (actually copy, in most cases), we will need first
of all to have some means of identifying where the data is coming
from, and where it is going to.
- Consider the possibility that there are many possible means
of identifying any address, such as we are so familiar with already.
- Local address, as in your neighborhood, or as in your township.
- Local address, as in your county, or as in your state.
- How about on your block, just 3 houses down the street, where
you don't know and don't care what the actual address is?
- How about an address that you don't actually know, but an
acquaintance of yours does?
- How about not the Post Office address, but the address of
the box number you have at that address?
- How about a P.O. Box ##, as an address.
- Ok, here's my point, when addressing memory inside of a computer,
there are a multitude of possible methods of determining just
where in memory you might gain access by some addressing scheme.
And this is only dealing with where (which is addressing)
to gain access of the data.
- Of course there are other considerations, like if we can
store and access data, what can we do with it?
- If the data is numbers, we might want to add/subtract/multiply/or
divide with new numbers, or some other mathematical manipulation.
Obviously, these would not be accomplished by just a few selections.
- This data may be our finances, addresses, or phone numbers.
- This data may relate to lighting and alarms for private homes
- This data may relate to the positioning of automated equipment
- There are many occasions where we need to move from one location
in our program to another. After all, we need to realize that
even our instructions need to reside somewhere (like in memory).
Please look at these
CPU considerations "A
Basic Introduction to Computer Systems (in 4 parts)"
on this site. I believe that the absolute most important thing
to consider in learning Assembly Language is centered in what
is know as "Addressing
Modes" (also on this site). These form the heart and
core of really understanding "how" a CPU accesses memory,
and will take some time and effort to master. I have also found
that the best way to understand these Addressing Modes is to start
with the Architecture of a CPU. The reason for this is actually
quite simple, in that the Addressing Modes are centered around
the Architecture itself.
For starters, let's look at a representation of the simplest
possible CPU Architecture:
Organization of Assembly Language Commands
within the design of the CPU:
- I think that the most logical (pun intended) way to start
looking at Computer Instructions and their method of decoding
is to remember what has been said about the Internal Architecture.
- Consider first of all that when these CPUs are designed,
it would be logical indeed to cluster various related commands
not only in common areas, but also utilize whatever common digital
elements they might incorporate.
- Load data from memory v.s. store data in memory would use
the same binary code, except for "1 binary bit".
- Jumping forward to a new location v.s. jumping backward to
a new location would use the same binary code, except for
"1 binary bit".
- Adding a new numeric value to an existing value v.s. subtracting
a new numeric value from an existing value would use the same
binary code, except for "1 binary bit".
- Preposterous as it might sound, it is quite possible for
you or any of us ordinary folks, to design and build a very basic
computer system when we understand these principles.
Let's look at some examples of some basic Assembly Language
and how binary bit patterns are used in contrasting codes:
- Probably the most basic commands to consider is "LOAD"
- We could assume a binary code of 0011 1010
for a "LOAD" command, and
- We could assume a binary code of 0011 0010
for a "STORE" command (note the single
binary bit difference).
- The particular bit that went low would simply be a signal
to a gate arrangement that we are going to "WRITE"
to memory, rather than "READ" from memory.
- It is the "0011 x010" that is intercepted and decoded
as a basic memory access for either of those two actions.
- Now let's consider an "ADD" vs "SUBTRACT"
command (consider that adding a negative number is subtraction):
- We could assume a binary code of 1100
0110 for our "ADD" command, and
- We could assume a binary code of 1101
0110 for our "SUBTRACT" command.
- Note the one bit difference again, where that bit high was
decoded as a adding a "Negative" number.
- If we want to increase or decrease a current value by only
"1", then instead of adding or subtracting, we could
"INCREMENT" or "DECREMENT" instead.
- Let's assume a binary value of 0011 1100
for the "INCREMENT", and
- Let's assume a binary value of 0011 1101
for the "DECREMENT".
- Note the one bit that is used at the Instruction Decoder
that the number is to be decreased.
- If we have a CPU that has a total of 8 Registers that are
capable of receiving or handling data, we would find that we
could use only 3 binary bits to determine which register is being
referenced. As an example, lets use the "INCREMENT"
command in reference to selecting one of those Registers. Lets
assume that 00xx x100
is the basic code for "INCREMENT", and that our Registers
are numbered as 0-7.
- 0000 0100 would be used to "INCREMENT"
- 0000 1100 would be used to "INCREMENT"
- 0001 0100 would be used to "INCREMENT"
- 0001 1000 would be used to "INCREMENT"
- 0010 0000 would be used to "INCREMENT"
- 0010 1000 would be used to "INCREMENT"
- 0011 0000 would be used to "INCREMENT"
- 0011 1000 would be used to "INCREMENT"
Register #7 - Note the binary progression that has occurred.
- To do a Register "DECREMENT" we could assume the
binary code that is almost like the one we used for "INCREMENT",
but with the changing of one single binary bit, to indicate the
difference, i.e. 00xx x101:
- 0000 0101 would be used to "DECREMENT"
- 0000 1101 would be used to "DECREMENT"
- 0001 0101 would be used to "DECREMENT"
- 0001 1001 would be used to "DECREMENT"
- 0010 0001 would be used to "DECREMENT"
- 0010 1001 would be used to "DECREMENT"
- 0011 0001 would be used to "DECREMENT"
- 0011 1001 would be used to "DECREMENT"
Register #7 - Note the binary progression that has occurred.
Now let's see what more we can accomplish
in understanding Assembly Language by certain scenarios:
Scenario #1: We have a row of numbered boxes that need
to be moved from another location that is only 50ft away",
and we have one boss and one worker to accomplish this task.
- Boss instructs the worker to pick up box #1, take the box
over to the new location, put box #1 down at the new destination
location, in a specific place.
- Boss now instructs worker to go back to the row of boxes,
pick up box #2, take the box over to the new location, and put
the box down in the new destination location, but obviously in
a specific place other than where box #1 was placed. Process
is continued until they run out of boxes.
- Obviously, this is a real "brute force" method,
which is terribly inefficient and screams for a better way (especially
if there is lots of boxes to be moved), because it was necessary
to direct this operation for each individual box.
Scenario #2: We have a row of a series of numbered
boxes that need to be moved from another location that is only
50ft away", and we have one boss and one worker to accomplish
this task, but this time we have a better approach.
- Boss instructs the worker to pick up (one at a time) the
boxes in sequential order, and then place them in the same sequential
order at the destination address, until 10 boxes have been moved.
- Boss leaves, and the worker does the necessary task. The
overall process is now more efficient.
Scenario #3: We have a warehouse with lots of materials,
organized by rows and rows of storage bins. The worker does not
yet know what materials are to be moved, nor their location(s).
The worker also does not know ahead of time how many are to be
moved, nor their destination. The information needed is available
on a particular clipboard hanging in a specific location. This
information will provide location of the materials to be gotten,
how many, and where they are going.
Scenario #4: In this situation, we have a large warehouse
with two workers handling the materials that are being moved
from one area in the warehouse to another area. There are two
clipboards in use, with one for each worker. The first worker
that goes and get the material, uses one clipboard to tell where
to find the items, and how many items are to be transferred.
The second worker has a second clipboard that tells where the
items received are to be stored, and also how many to expect
(consider a potential problem where either one of the two workers
were given the wrong count of materials).
Scenario #5: We have a driver who needs to take the
truck over to a particular location, and pick up some furniture.
The driver however, does not know the area, so another individual
goes along as a "navigator".
Scenario #6: We have the driver again, who needs to
go pick up another load of furniture from an unknown address,
except that it is 3 houses down the street from where the last
pickup was made.
Scenario #7: We have a "scavenger hunt",
where we go to a selected location to find where we should go
I think that we can see that there's nothing really
complicated about any of these scenarios, and if we go about
this carefully, we can figure out some of these types of CPU
codes in exactly the same manner, and without getting lost.
By the way, in the warehouse, if the boxes were heavy we could
have used a handcart. In the CPU we would call that "temporary
storage", as with the Register called the
Accumulator. A truck, used as a transport is also
"temporary storage". The clipboard(s) that had the
information pertaining to where these items are, would also be
represented in a CPU as simply a Register (or Registers)
that could reference Addresses in Memory. Also
on that clipboard was information that could be in a CPU as a
Register for the Count of items to
be transferred. It would be essential
to have these related thoughts in mind as we pursue just how
a Processor (CPU) does this. Also, remember that a CPU
Register may be simply a Data Latch, used as a Digital Data Register.
Now, we can begin to look at some
actual CPU codes and watch just how this is done. And while we're
at it it, we'll take a special look at those binary codes that
give us an insight into the Architecture of the CPU at hand.
There is an easier
way to learn and use Hexadecimal
To start with, "Hexadecimal" simply means
"hex (6) above decimal (10)", or "6 more
to Main Page
AssyLnge.html - SfE-DCS, ddf - 08/31/2001