Assembly Tutorial
Volume Number: 5
Issue Number: 12
Column Tag: Assembly Lab
Assembly Language for the Rest of Us 
By Jeffrey B. Kane, MD, Boston, MA
Note: Source code files accompanying article are located on MacTech CD-ROM orsource code disks.
Introduction and Purpose
I’ve always found that it’s the little things in life that hang me up. The grandiose
projects somehow seem to fall in place, but when I want to do a simple project, using
only obvious facts, I find that those facts must be so obvious, no one has bo thered to
write them down.
Most people who program do so to create little tools. As an engineer or scientist
might we write our code in a high level language like Pascal, C, Fortran, or LISP in
order to efficiently read and debug our code (e specially with tools from people like
Think Technologies and Coral Software). Once the code is up and running, we may
notice that one of our procedures, lets say one that crunches a lot of numbers using
SANE1, is taking up most of the processing time. By rewriting this one part of the
program we can speed things up dramatically, often 10 times or more!
This article is about assembly language. It’s not about writing a lightening fast
game or a new version of Excel™, rather it’s about using the minimum amount of
programing we can get away with in order to write a short but useful little bit of code.
Neither is it about writing a stand alone program in assembly, but instead we will take
a program written in Pascal and rewrite just one of it’s procedures in assembly
language, so the entire program can run much faster.
What we will do
In this article will recode a small subroutine whose mission in life is to take an
array and multiply each of it’s elements by a scalar constant. Although the program is
not the most dramatic use of assembly language, and the code we write will not be the
most elegant, hopefully it will be clear and easy to understand2. We will be
illustrating the steps needed to interface any code with a running Pascal program. I
chose to make use of the 68881 floating point processor3 in our program, not to add
complexity, but to illustrate how easy it is to use this chip. Motorola has made the
68881 appear simply to be an extension of the 68000 CPU4. To the programmer the
combination of a 68000 and a 68881 appear as a souped up 68000, just like the basic
version but turbocharged for numeric speed with a few more instructions and
registers added to it. If you don’t have this chip the same principles of programing
apply. You would simply replace the 68881 instructions with a few more 68000
instructions, but the programing logic would be the same.
MPW Assembler, LSP, and MDS
I will be using LightSpeed Pascal® to develop our main Pascal program. As I
explained above the basic program creates an array, then multiplies each number
within the array by a constant. LightSpeed is a great product for writing quick and
dirty programs, since you can debug and observe your variables as you go. It even has
an assembly level debugger built right in, so if you want to peek at the actual memory
to see exactly what your instructions are doing, you can. This is a great way to learn
the simple and predictable way each line in your program will effect memory.
We will also be using Macsbug™, a source level debugger that should be available
either from your local computer dealer5, most user groups, bulletin boards, and/or
commercial language products (including LightSpeed). With Macsbug we can look at
everything the Mac is doing, while it follows our assembly language instructions as
they execute, one line at a time. Tracing our code as it executes will make it clear that
each instruction has very predictable and simple results (Remember that if a
compressed piece of sand called the 68000 can understand what these instructions
mean, so can you!).
Finally we will be using the assembler built into the MPW shell6 (version
2.02). Consulair also makes a stand alone Assembler that was the standard of the
industry7.
In this article we will assume8 that you know a what a bit is (0 or 1), that 8
bits are stored in a byte, that 16 bits make up a word, and finally that 32 bits make up
a long word9. We also assume that have some idea of what a hexadecimal number is10.
The Pascal Code
First lets take a look at the Pascal Code:
{1}
PROGRAM TestSM;
USES
SANE;
TYPE
element = PACKED RECORD
empty : integer;
n : extended;
END;
vector = ARRAY[0..19] OF element;
matrix = RECORD
rows : integer;
columns : integer;
vecPtr : ^vector
END;
VAR
inVect : vector;
outVect : vector;
i : integer;
inMatrix, outMatrix : matrix;
scalar : extended;
error : integer;
FUNCTION ScaleMult (scalar : extended; VAR inMat, outMat :
matrix) : integer;
external;
BEGIN
ShowText;
scalar := 35;
inMatrix.rows := 0;
inMatrix.columns := 19;
inMatrix.VecPtr := @inVect;
outMatrix.rows := 0;
outMatrix.columns := 19;
outMatrix.VecPtr := @outVect;
writeln(‘scalar = ‘, scalar);
writeln(‘scalar, inMatrix, outMatrix, error, inVect’);
write(longint(@scalar), longint(@inMatrix),
longint(@outMatrix), longint(@error));
writeln(longint(@inVect));