home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 3
/
PDCD_3.iso
/
utilities
/
utilss
/
sasm
/
SAsm
/
Manual
next >
Wrap
Text File
|
1993-10-25
|
105KB
|
2,229 lines
SSSSS AAAA
SS AA AA
SS AA AA SSSSS mmm mmm
SSSS AA AA SS mm mmmm mm
SS AAAAAAAA SSSSS mm mm mm
SS AA AA SS mm mm mm
SSSSS AA AA SSSSS mm mm mm
Version 1.43
The Simple Assembler for the Archimedes
Copyright David Holden 1991,1992,1993
_______
____|__ | (R)
--| | |-------------------
| ____|__ | Association of
| | |_| Shareware
|__| o | Professionals
-----| | |---------------------
|___|___| MEMBER
CONTENTS
Page
Preliminaries
Introduction ........ 1
Licence to Use ........ 2
How to Register ........ 2
Advantages of Registration ...... 2
Licence to Copy ........ 3
Using SAsm
Invocation ........ 4
Null Parameters ........ 5
Source Filenames ........ 6
Reconciliation of Wildcards ..... 6
Order of Assembly ........ 7
Length of Source File ........ 8
Line number space ......... 8
A short demonstration ........ 9
The Source File
Source File Syntax ........ 10
Warnings and Errors ........ 10
Comments ........ 11
Directives ........ 11
#ORG ........ 12
#SIZE ........ 12
#TYPE ........ 12
#END ........ 13
#INCLUDE ........ 13
#OBJ ........ 14
#LIB ........ 14
#ERRFILE ........ 14
#CLI ........ 14
#VERBOSE ........ 14
#QUIET ........ 14
#XREF ........ 14
#NOXREF ........ 14
Defining registers etc. ........ 15
Conditional Assembly ........ 15
Assembly Loops ........ 16
Assembly Listing ........ 16
Macros
Macro Functions - Pro/Con ...... 17
Expanded Macros - Pro/Con ...... 17
Macro Names ........ 17
Expanded Macros
Defining expanded macros ........ 18
Macro parameters ........ 18
Local labels in macros ........ 19
Special features ........ 10
Examples ........ 20
Errors in expanded macros ....... 21
CONTENTS
Page
Macro Functions
General ........ 22
Built-in Functions ........ 22
FNgap ........ 23
FNset ........ 23
FNadr ........ 23
FNdw and FNdd ........ 23
FNdb ........ 24
FNmov ........ 24
Extra Mnemonics
DW and DD ........ 25
DB ........ 26
ADRL ........ 27
MOVL ........ 27
DIV ........ 28
Enhanced 2nd Operand ........ 29
Labels
Global Labels ........ 30
Local Labels ........ 30
Local Label Scope ........ 30
Local Label Example ........ 31
Forward Branch to 00 ........ 31
The Macro Library
Using the Macro Library ........ 32
The 'L' parameter ........ 32
The 'V' parameter ........ 32
SAsm$Lib OS variable ........ 33
Preparing a Library ........ 33
Length of Library file ........ 34
SAsm and the Desktop
New features ........ 35
Using from the desktop ........ 35
Problems ........ 37
Release History ........ 39
Registration Form ........ Endpiece
Page 1
-=O=- INTRODUCTION -=O=-
A long time ago when I found I needed more facilities than the Basic
assembler offers I tried Acorn's AASM. My personal opinion of AASM is
that it is overpriced, clumsy and, for many purposes, LESS powerful
than the (free!) Basic assembler. I therefore decided to write my own,
provisionally titled BAsm. As usual it had to be fitted in with other
things, and meanwhile I needed an assembler. I continued to use the
Basic assembler for short utilities and AASM for longer ones. Soon I
found I was using AASM less and less as I gradually added bits to the
Basic assembler to give the additional facilities I needed.
To make life easier I wrote a 'pre-processor' for the Basic assembler
as a stop-gap until I finished BAsm. Gradually it was improved and
with each improvement the need for BAsm receded and work on it assumed
a lower priority. Eventually my stop-gap program assumed a life of
it's own and had become so powerful that it could do just about
everything I wanted. At this point I realised it would be useful to
others as well. I re-wrote the program, making lot's of improvements,
and named it SASM - Simple ASseMbler for the Archimedes
Don't be put off by the word 'Simple'. Unless you are re-writing
Impression SAsm will probably fulfil all your needs. Simple is
intended to describe its ease of use. Its main limitation is that it
cannot produce output in AOF (Acorn Object Format) for linking to 'C'
(ugh!) or other languages. If you really must write in 'C' I'm afraid
you are stuck with AASM until I get around to finishing BAsm. It also
cannot assemble Floating Point opcodes although you could easily add
Macros to do this. If you really must use them (I have never found the
need) let me know and I will try to include the facility.
SAsm is not actually an assembler. It is a pre-processor for the Basic
assembler. Don't worry about this. As far as the user is concerned
SAsm works with Text source files and behaves like a 'proper'
assembler. It has lots of facilities that the Basic assembler normally
lacks, local labels, multi-file assembly, error reovery, etc. yet at
the same time the syntax will be familiar to anyone who has used the
Basic assembler. You also have the power of Basic available with its
Mathematical, Conditional Assembly and Expression Evaluation abilities
If you are not an expert at using the Basic assembler I suggest you
read the file 'Tutorial'. This won't teach you to write machine code
but it does explain how to write Macros and use Conditional Assembly
with the Basic assembler and will help you understand SAsm better.
Please read carefully the 'Licence to Use' and 'Licence to Copy'
before you use/copy SAsm.
David Holden
39 Knighton Park Road
Sydenham
London SE26 5RN
081 778 2659
Page 2
SAsm is SHAREWARE, it is NOT Public Domain
ssss h h aaa rrrr eeeee w w aaa rrrr eeeee
s h h a a r r e w w a a r r e
ssss hhhhh a a rrrr eeee w w w a a rrrr eeee
s h h aaaaa r r e w w w aaaaa r r e
ssss h h a a r r eeeee ww ww a a r r eeeee
-=O=- LICENCE TO USE -=O=-
This program is distributed as SHAREWARE. It is NOT Public Domain. This
means that you are only licensed to use it for a period of THIRTY DAYS.
At the end of that time you must either stop using it or REGISTER.
Failure to comply with this condition is a Breach of Copyright and is
now recognised in almost all countries as an offence.
Use of ANY version of SAsm for any TRAINING or EDUCATIONAL purposes
without payment of the Registration Fee is ABSOLUTELY FORBIDDEN.
-=O=- HOW TO REGISTER -=O=-
Registration costs just Eight Pounds. I have made the last page of this
Manual a Registration Form. Please use it when you register as it helps
me to keep my records tidy. Fill it in, preferably adding comments, and
post it to me. Don't forget your cheque for Eight Pounds. Write as much
as you wish, I do take notice of comments and suggestions.
Each assembler for the ARM processor will produce slightly different hex
values for the same assembler mnemonics. SAsm leaves its 'fingerprints'
on all the code produced. I can tell if a program was assembled using
SAsm. I will take action against ANYONE who uses SAsm and distributes
code WITHOUT REGISTRATION in breach of this licence
Advantages of Registration
--------------------------
The first advantage is that you will not, of course, be breaking the
law. Registration costs just 8, so it's not exactly expensive. However
there are some material advantages.
When you register you will receive your personal copy of the latest
version of SAsm which can use external Macro Libraries This enables SAsm
to load Macros automatically during assembly. You will also receive the
tools which will let you create Macro Libraries. This makes your code
much simpler because you don't need to include all the macro definitions
within it before you call them.
You will also have the right to FREE UPDATES. Once you have registered
you can send a disc to me with a stamped, self addressed label at any
time for a copy of the latest version. To take advantage of this offer
you MUST include on the disc a copy of your personal copy of SAsm.
You will also be entitled to free or very low cost upgrades to any
future assemblers for the Archimedes that I produce, even if these are
not part of the SAsm 'family'.
Page 3
-=O=- LICENCE TO COPY -=O=-
If you are a Sysop or running a P.D. or Shareware library PLEASE READ
THIS SECTION CAREFULLY.
1. The Author retains full copyright to this program and all
the material associated with it.
2. Any private individual is permitted to GIVE copies of SAsm
to his/her friends. Only P.D. or Shareware libraries and BBS
which have been given specific permission by the author to
do so are permitted to distribute SAsm. Any distribution by
any organisation or for any reward whatsoever whether in fee
or in kind without this permission is strictly forbidden and
will be treated as a Breach of Copyright, even if this fee
is merely intended to cover media cost.
3. You may not make any changes to the program or documentation
and you must include the Source directory and its contents
and the Tutorial and Manual files.
4. You may not make any charge for this program or for any
additional material you might supply. You may charge a
reasonable fee to cover copying, media, postage etc.
5. You may not under any circumstances distribute copies of any
version of SAsm which is available only to registered users
who have paid the registration fee. This version can ALWAYS
be distinguished because it displays the name of the
registered user after the copyright message whereas the
version which may be freely distributed displays the word
'UNREGISTERED'.
6. You must not distribute any version of the 'MakeLib'
application. This is for the use of Registered users ONLY.
If you have any problems or suggestions for improvements to SAsm please
write or phone. If you write with an enquiry please enclose an SAE. If
you prefer to telephone I am normally available on weekday evenings.
David Holden
39 Knighton Park Road
Sydenham
London SE26 5RN
081 778 2659
Page 4
-=O=- USING SASM -=O=-
SAsm is a 'Transient' program. This means that when it is invoked by
typing it's name at the OS '*' prompt it is loaded from disc and Run.
This is not normally a problem because SAsm is quite compact, about
16K. If you have a hard disc put SAsm in your Library directory. If you
have only a single floppy drive then copy SAsm to each working disc, it
won't take up much disc space.
From version 1.30 onward you will find two versions of SAsm on the
distribution disc. One is the transient application and this is
probably the best way to use SAsm if you have a hard disc as you can
simply copy it to your Library directory and it will automatically Run
whenever you type its name. The other version is a Relocatable Module
called SAsmMod. This will be the preferred method if you don't have a
hard disc. Just load the Module by double-clicking on it and it will
then run from the RMA whenever you type 'SASM' in exactly the same way
as the transient program runs from disc.
Note that the Module version of SAsm does NOT actually run from the
RMA. When you invoke it the program code is copied down to &8000 and
run from there. It will therefore have the amount of RAM available that
you have set for the 'Next Slot' in the Task window.
The full syntax of the command string for SAsm is;
SASM <source file list> [object filename] [error filename] [L] [X] [V]
Only <source file list> is compulsory, the others are optional.
This means after *SASM leave one or more spaces and then type the name
of your source file(s). You can have as many as you like, separated by
commas. The full meaning of <source file list> is quite complex and for
the complete explanation read the section titled 'Source Filenames'.
After the source file(s) leave a space then type the name of the Object
File. This is the name that will be given to your assembled code when
it is saved. If you don't type an Object Filename SAsm will assemble
all the files but won't save the finished product. It may seem strange
that you should wish to do this but if you just want to check for
errors or find out how long the finished code is it can be useful.
The next parameter is the name of the Error File. Unlike the Basic
assembler SAsm will display an error message and try to continue if it
finds an error in your code. If you have a lot of errors the first ones
will soon scroll off the screen and get lost. If you type a name for an
error file all these error messages will be sent to a file and you can
load them into one window of your Editor with the source code in
another so that you can easily find and correct them.
If you type a letter 'X' after the error filename SAsm will cross
reference (X-ref) all labels in your source as it loads the files and
report any duplicates. If a duplicate is found a warning message will
be displayed with the name of the label and the file and line number in
which it occurs. You can include this parameter each time but normally
it is only needed the first time you link all your files as sometimes a
duplicate label is perfectly valid. For example I often use 'loop' or
Page 5
'bak' repeatedly and don't want a screen full of warnings.
If you type the letter 'L' then SAsm will NOT try to load any Macro
definitions from the Library, even if one exists. See the section on
the Macro Library for an explanation of this.
The 'V' parameter is used to make SAsm 'verbose' when loading Expanded
Macros from a Library. As each macro is loaded it's name will be
displayed. This is not normally needed but the facility has been
included in case you want to check whether SAsm is using a macro
defined in the file or one in the Library.
You can of course use both more than one of these separated by spaces.
From version 1.40 all of these parameters (except of course the first
file name) can be defined within the source file. You will normally
therefore need only to type '*SASM <filename>' to assemble even the
most complex project.
Null Parameters
---------------
You will notice that these names must appear in order. So what do you
do if you want an error file but no object file?, or a X-ref but no
Error or Object file? If these are defined within the source there is
no problem but for a simple single-file source you may not want to be
bothered with this so SAsm accepts the ~ character or any filename
beginning with ~ as the equivalent of no filename. For example, to
assemble the source file 'My_Prog' without producing an object file but
listing all the errors in the file 'Errors' you would type;
*SASM MyProg ~ Errors
I anticipate that a version of SAsm with a complete desktop 'front end'
will appear in the near future but for the present can run it from
within 'Task' window if you wish. This will be described later.
Page 6
Source Filenames
----------------
The source filename list can be a single filename or a series of names
separated by commas. Most users will probably use a 'make' file with
'INCLUDE' filenames to assemble a complicated project but you should
understand the full command line syntax ensure that you know exactly
how SAsm operates with wildcarded filenames.
To assemble the files Start, Middle and End in that order into the
object file Code you would use;
*SASM Start,Middle,End Code
This assumes the files are all in the Currently Selected Directory
(CSD). Each filename can of course have a path as well. If you have
some standard sub-routines called Subs in directory $.Source.Routines
you could use;
*SASM Start,Middle,$.Source.Routines.Subs,End Code
SAsm loads the files in the order in which you type their names and
treats them as if they were one big file. You can therefore break your
source up into small chunks and sub routines which can be easily edited
and tested. You will soon find you acquire lots of standard routines
which you want to assemble with your program. The easiest way to avoid
all this typing is to program a function key with the command. For the
previous example if you type;
*Key 5 *SASM Start,Middle,$.Source.Routines.Subs,End Code|M
you need only press F5 to assemble your code. This saves the repetitive
typing but as the length of this is limited to 255 characters by the OS
it may not be enough to accommodate a list of path/filenames. SAsm
therefore accepts wildcards in the source file list.
Reconciliation of Wildcards
---------------------------
At first it might seem no 'filtering' of wildcards in filenames is
necessary. If you put all the source files in sub-directory 'Source' of
the CSD then typing *SASM Source.* Code would assemble them all into
the object file Code with no problems. In real life things aren't that
simple. For example, suppose that you wish to make an alteration to one
of your source files but keep the original in case the change doesn't
work (always to be advised!). You make your alterations, change the
name of your original, and then assemble the code. The only problem is
that SAsm would assemble BOTH files, the original AND the new. You
could of course avoid this problem by moving the original to another
directory but this would soon become very tedious.
SAsm has a rigid system of deciding which files to assemble. This was
designed to work with the way I write my source files. If you don't
like it let me know and I will try to accommodate your preferences but
please try my way first, it's the result of a lot of experience and you
might find you like it.
Page 7
SAsm works it's way through the list in order. It first finds all the
names which fit the wildcarded first name in your file list.
SAsm now rejects any file that doesn't have a filetype of 'Text' (FFF)
or 'Data' (FFD). This avoids trying to load a previous object file or
other program file if this was saved to the same directory. As all text
editors on the Archimedes save output as 'Text' by default this should
not be a problem. Data files are accepted because I sometimes use other
tools to create screens, sprites, etc. and when these are saved I set
the filetype to Data so I know what they are. You may also wish to use
window definitions created with !FormEd and these can be included in
the same way. If you get a 'File not found' error but you can see the
file exists it is probably because its filetype is not &FFF or &FFD.
The remaining files which fit the wildcard name are then examined and
loaded IN ALPHABETICAL ORDER. Any file which has a digit 0-9 at the end
of its name is examined and if it has the same name as the previous
file but with a different number it is ignored.
What this means is that if you give all your source files a name ending
in a number the file with the LOWEST number will be loaded and the rest
ignored. This works because the lowest number is also the first
alphabetically. I start out at 99 and work my way down, so each version
is progressively called Name_99, Name_98, Name_97 etc. This system
operates beautifully with TWIN (Acorns programmers text editor) because
if I type 'Name*' as the filename to load into TWIN it will load the
one with the lowest number, ie. the latest. If you use Edit to write
source files then the latest version will always be the first file in
the directory viewer.
When all the files with names which fit a wildcarded filename have been
loaded SAsm will get the next name on the list and so on until all the
names have been dealt with.
Order of Assembly
-----------------
Remember that SAsm assembles the files which can be matched to each
wildcarded name alphabetically. To return to the previous list with
'Start, Middle and End' if you use '*' to match all of these files then
they will be assembled in the order 'End, Middle, Start' which is not
what is required. As it is normally only the first and sometimes last
files whose order is important it is fairly easy to ensure that they
are assembled in the correct order by placing an extra digit at the
start of the name if necessary. For example renaming the files 'aStart,
Middle, zEnd' would ensure that they are assembled in the correct order
while retaining meaningful names.
Since SAsm expands and reconciles wildcarded filenames in this way you
don't need any complicated 'make' utilities to assemble a long list of
source files. In fact the additional facilities offered by the INCLUDE
directive make this even simpler.
Page 8
Length of Source Files
----------------------
Because SAsm loads all the files into memory at once in might seem that
the total length of these files could not exceed the usual 640K (or
whatever you have set 'Next Slot' to) which is available when you press
F12. In fact this is not the case. As SAsm loads each file it removes
all the spare spaces and assembler comments. If, like me, you indent
every line and use lots of comments you will probably find your source
files shrink to about 50% of their original size. Even allowing for the
memory required for variables, the assembler commands etc. you should
find that SAsm can load over 1MB of source with the usual 640K slot. If
you are writing programs which need more than this then perhaps you
should be writing your own assembler and trying to sell it to me!
Line number space
-----------------
When the pre-processed code is passed to the Basic assembler it must be
given line numbers so that Basic can understand it. This means that 3
bytes must be added to the start of each line. If there is not enough
room for this SAsm will attempt to relocate the file in memory, and a
message to this effect will be displayed. This is unlikely to happen
unless you are writing code with more than about 9000 lines.
It is possible that there simply isn't enough RAM available for
relocation and in this case SAsm will be unable to continue. If this
happens there are two possible solutions. The simplest is to make more
RAM available. Bring up the Task Manager window on the desktop and
increase the size of the 'Next Task' allocation. On a 1Mb machine you
may need to 'kill off' some tasks to be able to do this.
If you cannot make more RAM available you will need to reduce the
number of lines in your source file. There is no point in removing
comments, column indents etc. because by the time this error occurs
they will all have been stripped by SAsm anyway.
Page 9
A short demonstration:
Copy the file SAsm and the complete 'Source' directory to a blank disc
in drive 0. Now press F12 to leave the desktop and type 'MOUNT 0' at
the OS '*' prompt. To assemble the demonstration program type;
SASM Source.H* Hello
The disc drive will start and after the SAsm copyright line you should
see the messages;
Loading Source Files:
Source.Hello_A
Source.Hello_B
Source.Hello_C_50
Pre-processing completed - starting assembly
Pass 1
Pass 2
0 Errors
Code &xx bytes - Saved as 'Hello'
If you now type 'CAT' you will find that a new file 'Hello' has
appeared on the disc. To run this program, which simply displays a
couple of messages, just type 'Hello'.
If you examine the contents of the directory Sources you will find that
as well as Hello_A, Hello_B and Hello_C_50 (and several other files)
there is Hello_C_52. Since this file has a higher number than
Hello_C_50 it was ignored.
Now repeat the exercise but hold down the SHIFT key when you press
RETURN after entering the SAsm command line as previously. Everything
will seem as before but this time when you type *Hello to RUN the
Object code some of the messages will be different. This is a simple
example of Conditional Assembly, some of the code being changed if the
SHIFT key is held down during asssembly.
I suggest that you load these three files into Edit and examine them.
They are not a good example of compact or well written code but they do
illustrate the layout of a multiple SAsm source file. You will notice
the use of the Conditional Assembly section which produces the two
different versions. Note also that branch instructions can be used to a
label in another file demonstrating that labels are global.
You will also see the use of a macro 'print_string'. This would be more
efficiently coded using OS_Write0 but it illustrates how Macros are
written and used.
The other files 'Local' and 'Immed' are examples to illustrate the use
of local labels, SAsm's simplified immediate 2nd operand instructions
and Expanded Macro's. These may be assembled and examined in a similar
manner.
Page 10
-=O=- THE SOURCE FILE -=O=-
Source file Syntax
------------------
I assume that the reader is familiar with the Basic Assembler.
Reference will be made to it and attention drawn to differences between
it and SAsm where they occur. Although the syntax used by SAsm is
similar to the Basic Assembler this applies only to the actual assembly
language itself. You can forget about square brackets, OPT, P%, O% and
all the things that are necessary before you can use the Basic
Assembler. The biggest change is that if you have previously used the
Basic Editor the source files for SAsm, like all assemblers, are TEXT
files and must NOT have line numbers.
One of the nice features of SAsm is this similarity. This isn't an
accident. Firstly SAsm actually uses the Basic assembler to do much of
the work. Secondly it was designed from the start to be a 'step up'
from the Basic assembler so even it's most advanced features will be
very quickly mastered by anyone who is familiar with the Archimedes
'built-in' assembler.
You won't therefore need to spend ages learning a whole new language
and you will be able to convert your old assembler programs into SAsm
format very easily and quickly. Normally this takes only a few minutes
with a straightforward program.
Throughout this Manual reference will be made to the 'hash' character
'#' which is the character on the key at the top right hand corner of
the numeric keypad. If that appeared in your printout as a pound sign
then your printer is set to the English character set so you will just
have to read the file as if it had printed a hash. There are no pound
characters in this Manual.
Warnings and Errors
-------------------
In the following sections reference will be made to Warnings, Errors
and Fatal Errors.
Warnings are issued if SAsm finds you have omitted or wrongly placed a
directive. The code will still be assembled and saved. Warnings will
not be written to the Error file.
Errors are faults from which SAsm can recover but which make the code
useless. Unlike the Basic assembler SAsm will try to continue after
reporting an error as there may be others to report, but the assembled
code will not be viable so no Object file will be produced.
If SAsm reports an error in the first pass it will not attempt a second
pass. You may therefore need two attempts to correct all the errors.
A Fatal Error is an error from which SAsm cannot recover or which is so
serious that there is no point in continuing. An error in a Macro
Function or a missing file are examples of Fatal Errors.
Page 11
Comments
--------
SAsm defines a comment as EVERYTHING on a line after a semi-colon ';'
or a backslash '\'. SAsm therefore conforms to the syntax used by most
assemblers which differs from the Basic assembler. The Basic assembler
is almost unique in using the colon ':' as a statement delimiter. While
SAsm still recognises ':' and allows more than one mnemonic on a line
Basic regards ':' as the end of a comment and tries to assemble
anything on the line after a ':', even if the ':' is in a comment. For
example the following line using the Basic assembler;
mov r1,#0 : \ mov r1,#1 : mov r2,#2
would be assembled as mov r0,#0 followed by mov r2,#2 The middle
instruction would be ignored because Basic recognises the '\' and
regards it as a comment but continues assembling when it finds the ':'
later in the line. Using SAsm you would get ONLY mov r1,#1 as
everything on the line after the '\' is a comment.
The exception to this is where a semi colon (;) is not preceded by a
space in a line which is to be passed to Basic. This has been done so
that you can use ';' in PRINT statements to display information during
assembly. If you do use ';' in a Basic line to define a comment make
sure that it is preceded by a space or it will cause an error.
Directives
----------
It is possible to include 'Directives' in your source. In fact some
directives are necessary for the proper operation of SAsm. Any line in
which the first non-space character is '#' is a directive. This
character was chosen because it will be familiar to most programmers
who have used 'C'. If SAsm doesn't recognise what immediately follows
the '#' it will assume it is a valid Basic statement and so the line
after the '#' will be passed to Basic.
You can use SAsm without any preliminary directives in your source
file. Unlike the Basic assembler you can begin by writing mnemonics
straight away. If you do this SAsm will start assembling your code to
run from '0000'. This doesn't matter as SAsm will normally produce
position independent code unless you have included specific references
to addresses within your source.
The '#' character can have spaces before and after it to improve
legibility if you wish, they will be ignored by SAsm, but it MUST be
the first non-space character on the line. Directives should be the
only item on the line although you may include comments if you wish.
All directives are case insensitive. Where a directive is to be passed
to Basic it's case and syntax must conform to that required by Basic.
Where a comment is included in a directive which is to be passed to
Basic it can still be preceded by ';' or '\' rather than REM, but see
the note under 'Comments' above.
There must be at least one space after a directive where it is followed
by one or more parameters.
Page 12
#ORG
This defines the address the code will be assembled to run at. The
syntax is # ORG <number> where <number> is a valid address. If
<number> is in hex, as it normally will be, it should be preceded by
the '&' character. If no #ORG directive is found assembly will start at
location 0 and a warning message will be displayed.
The #ORG directive must obviously appear BEFORE the first assembler
statement. If an #ORG directive is found after the first assembler
statement a warning message will be displayed and the code will be
assembled to start at location 0.
There must be at least one space between the word 'org' and the number
which follows. This applies to all the following directives.
Note - ORG replaces the ADDR directive used in early versions. ADDR is
still supported for backwards compatibility but ORG should be used in
all new work as ADDR may be dropped in the future.
#SIZE
This advises SAsm of the expected size of the code so it can reserve a
large enough buffer for the assembled code. The full syntax is #SIZE
<number> where <number> is the estimated maximum size of the code. if
<number> is in hex it should be preceded by a '&' character.
If there is no #SIZE directive before the first assembler statement a
warning will be given and 64K will be allocated for the code. Any #SIZE
directives after the first assembler statement will be ignored.
#TYPE
This defines the filetype you wish your assembled code to have. Syntax
is #TYPE <filetype> where <filetype> is a valid Archimedes filetype. If
<filetype> is a number it should be in hex, though it need not be
preceded by a '&' character. If it is a text representation of a
filetype it must be in quotes, for example;
# type FF8
# type "Absolute"
If you do not include #TYPE the assembled code will be saved as an
absolute block of memory with no filetype.
Unlike the previous examples #TYPE can appear anywhere in the source.
If more than one #TYPE directive appears the last one will be used.
The most common filetypes are &FFC for a position independent Utility,
&FF8 for an Application to be loaded and Run at &8000 and &FFA for a
Relocatable Module.
The upper case versions of these, namely ORG, ADDR, TYPE and SIZE, are
reserved words and must not be used as variables anywhere in your code.
Page 13
#END
This directive, which takes no parameters, should be placed at the end
of your assembler and before any Macro Function definitions. Anything
after #END will be passed to Basic without the need for a '#' at the
beginning of the line. When SAsm finds #END it assumes it has reached
the end of the code and everything else is Macro Function definitions
If DEFFN is found at the start of a line indicating that a Macro
Function definition has been found before an #END directive a warning
will be given and all subsequent lines will be passed to Basic.
#INCLUDE
This allows additional files to be 'included' as well as the ones
specified at the command line. The word INCLUDE should be followed by
at least one space and then a single filename. Unlike files loaded from
the command line only the first file which matches the required name
will be used and no checks will be made on its filetype.
The INCLUDE directive in SAsm is different to its equivalent in 'C'.
SAsm does NOT 'insert' the file at the point at which the directive
occurs. Instead it creates a 'queue' of any INCLUDE filenames it finds.
When it reaches the end of the current file it goes to this list and
loads the first name in the queue. When that file has been dealt with
it loads the next name and so on until the queue is empty. If one of
the 'include' files contains more INCLUDE directives these names are
added to the END of the queue. When the queue is empty SAsm returns to
the filenames specified at the command line and carries on as before.
INCLUDE files can therefore have further INCLUDE directives which files
can contain their own INCLUDEs and so on.
If you have a complex program which consists of a lot of small pieces
of code and sub-routines you can create a 'master' file which will
contain the #ORG, #TYPE etc. directives and then a list of #INCLUDE
directives to define the files required to make up the program. This
operates in the same way as 'Make' files for other assemblers and
compilers. SAsm will simply load each INCLUDE file in your 'primary'
file in the order in which you have listed them. As INCLUDE files are
subject to similar discrimination to filenames typed at the command
line the 'trailing number suffix' system can be used to assemble the
latest versions.
For example, a file containing just the following would assemble the
named files with the lowest trailing numbers in the chosen order.
# org &8000
# type "Absolute"
# size &1000
# include start_*
# include middle_*
# include end_*
Page 14
#OBJ
This defines the name of the Object file. The syntax is #OBJ <filename>
where <filename> can be any valid path/filename. If you type an object
name at the Command Line it will override any #OBJ directive. You can
therefore include an #OBJ directive in the source but assemble a
different version if you choose by typing an Object name at the CLI.
#LIB
This defines the Library file to be used. It will override any Library
defined in the SAsm$Lib variable. Using #LIB without a filename will
force SAsm NOT to use a Library and so is equivalent to the 'L' switch.
#ERRFILE
Defines the error filename to be used. Again any error filename typed
at the command line will override this directive.
#CLI
Anything on the line after this directive will be passed DIRECTLY to
the Archimedes operating system CLI. It can be regarded as equivalent
to a '*' command as used in a Basic program. It is not like the 'OSCLI'
command in Basic as no substitution is carried out first. You should
not put any comments on the line after a #CLI directive.
# VERBOSE
Equivalent to the command line 'V' switch to force display of names of
macros inserted from a Library. The advantage over the 'V' command line
switch is that it can be inserted at any point and so need not show all
the expanded macros, only those used after the directive is used.
# QUIET
Switches off display of macro names. You can use this with 'verbose' as
often as you wish to switch on and off display of expanded macro names.
#XREF
Switches on label cross reference. Once again the advantage of this
over the 'X' switch is that it only takes effect from the point at
which it appears.
#NOXREF
Switches off label cross reference. Can be used as often as required
with the previous command to toggle x-ref on and off.
Page 15
Defining Registers etc
----------------------
In order to simplify writing code it is normal to give the C.P.U.
registers names. In Basic this is done by assigning the chosen name a
number using the syntax <name>=<number>. The same method is used with
SAsm except that you must precede your definitions with '#'.
For example, to define register 5 as 'count' and register 6 as 'flag'
# count = 5
# flag = 6
or alternatively
# count=5:flag=6
You can use this method to define SWI's, offsets in a data area, in
fact anything you wish. Since these are normal Basic variables you can
use integer and string variables if required.
R13,R14 and R15 are pre-defined as 'sp', 'link' and 'pc' in upper and
lower case as these are the normal definitions for these registers.
All registers are pre defined as their equivalent 'r' and 'R' numbers.
Basic doesn't recognise a number like 'r4' as meaning register number 4
except when it is an assembler operand. If you try to pass 'r4' as a
parameter an error would be generated. With SAsm you can use r0-r15 or
R0-R15 as they have been pre defined.
Conditional Assembly
--------------------
This works as with the Basic assembler, normally using IF THEN,
(ELSE), ENDIF. If you are unfamiliar with this technique please read
the 'Tutorial' file which explains it.
With SAsm there is no need to bother with assembler brackets, etc. Just
put '#' in front of the lines which form the conditional block.
# IF <condition> THEN
......... ; some code
.........
.........
# ELSE
......... ; the alternative code
.........
.........
# ENDIF
Don't forget the 'THEN' at the end of the 'IF' line. The 'ELSE' section
is of course optional.
If an error occurs in a conditional section you may find subsequent
'ELSE found without IF' or 'ENDIF found without IF' errors occurring.
This is not significant, it just means the assembler has 'forgotten' it
was in a conditional section when the original error was discovered.
Page 16
Assembly Loops
--------------
When using the Basic assembler it is common to use FOR-NEXT loops to
fill an area of memory, eg.
........ ;normal code
] :REM exit assembler
FOR I%=0 TO 255
[ OPT PASS
EQUB &FF ;fill 256 bytes with &FF
]
NEXT
[ OPT PASS ;back to assembler again
........ ;normal code
You could still use this method with SAsm if you wish but it is simpler
........ ;normal code
# FOR I%=0 TO 255
EQUB &FF
# NEXT
........ ;normal code again
In fact SAsm has a much better way to fill an area of memory with a
value using the DB directive.
Assembly Listing
----------------
SAsm will not normally produce an assembly listing. Not only would this
obscure any Error or Warning messages it also slows down assembly. If
you need to see a part of your code to make sure that it being
correctly assembled then you can easily do so.
Where you want the listing to begin insert a line in the source;
# IF Q%=6 Q%=7
and where you want the listing to end;
# IF Q%=7 Q%=6
This will produce a screen listing during the second pass between these
two lines.
Page 17
-=O=- MACROS -=O=-
Sasm supports two types of Macros. Expanded Macros and Macro Functions.
There are advantages and disadvantages with each type. Both can be
included in your Macro Library.
Macro Functions - Pro/Con
-------------------------
These are normal Basic Functions and their use and format is fully
described in the 'Tutorial'. They have two disadvantages. Firstly
because they are Basic Functions you must include assembler brackets,
OPT setting, etc. and forward branches are awkward. Secondly it is not
possible to use any of the special features of SAsm such as local
labels, db, adrl, movl, etc. within a Macro Function. Also you cannot
call or define an Expanded Macro from within a Macro Function.
A serious disadvantage is that SAsm cannot recover from an error in a
Macro Function. Such errors are always Fatal and will produce an error
message giving a line number that does not exist in the file.
The first advantage is that this type of macro is not 'expanded' by the
pre processor so that no matter how many times you call it it doesn't
take any more memory. The second advantage is a consequence of this and
will only apply if you use a Macro Library without a hard disc. This is
because a Macro Function only appears once, at the end of the code, and
so only one disc access to load it from the Library will be required.
Expanded Macros - Pro/Con
-------------------------
These are short sections of code which are physically inserted into the
file each time the Macro is invoked. The big advantage with this method
is that you can use all the special features of SAsm, local labels,
etc. You can also call Macro Functions or other Expanded Macros from
within this type of macro.
Because Expanded Macros become part of the normal code SAsm can
normally recover from errors in them in the same way as it can recover
from most other errors.
The disadvantage is that an Expanded Macro must be defined before it is
used, although it can be defined in your Macro Library. Also as the
macro code is inserted into your source each time it is used more
memory is required although it is unlikely to be a problem in practice.
Macro Names
-----------
Because Macro Functions and Expanded Macros are completely different
they can have the same name. You can even have Expanded Macros and
Macro Functions with the same name in your Library. SAsm will sort out
which to use.
Page 18
-=O=- EXPANDED MACROS -=O=-
An Expanded Macro must be defined before it is used. If you are using a
Macro Library it can be defined in the Library and SAsm will then load
it from there.
If you have defined a macro in your source file and one of the same
name exists in the Library then the macro in the source file will be
used in preference to the one in the Library.
Defining Macros
---------------
An expanded macro is defined as follows.
# SM <name>
........ \
........ > Normal SAsm code
........ /
# EM
and invoked by -
@ <name>
In both cases <name> is the name given to the macro and, with any
parameters, is case sensitive. As with other SAsm directives the '#'
used by #SM (Start Macro) and #EM (End Macro) must be the first
non-space characters on the line. Similarly the '@' character must be
the first non-space character on the line.
Whenever SAsm encounters a '@' it will match the following name with
any previously defined macros. When it finds one it will physically
insert a copy of the code into the file. If there are any LOCAL labels
in a macro they will be unique within that definition, but all
non-local labels will be global.
Macro Parameters
----------------
You can pass parameters of almost any type to an Expanded Macro. The
full syntax of the defining line of the start of a macro is -
# sm <name> <param name 1> , <param name 2> , <param name 3> ....
and of the calling line -
@ <name> <param value 1> , <param value 2> , <param value 3> ....
where <name> is the actual name given to the macro, <param name> is the
name given to each parameter and <param value> is the value that each
parameter will be given when the macro is expanded.
Page 19
A parameter is actually a Global Variable and should conform to the
variable type that Basic would use for the type of value that it will
hold. It can be an Integer, String or Floating Point variable.
Similarly the parameter passed must be suitable for that type of
variable. It need not be a constant value. Any expression which can be
evaluated to the correct type of variable may be used.
There must be at least one space between <name> and the first parameter
and parameters are separated by commas.
In fact you will recognise that the syntax has deliberately been made
identical to the way that parameters are passed to Basic Functions and
Procedures except that there are no brackets.
Local Labels in Expanded Macros
-------------------------------
You can use local labels in expanded macros and these should conform to
the syntax used elsewhere. You MUST start any local labels in a macro
definition with '00' to ensure that the labels used will be unique.
When the macro expansion ends the 'flow' of local labels in the main
code before the macro was used will be restored. A macro, with its own
set of local labels, can therefore exist within the area of 'normal'
local labels without confusion. In practical terms this simply means
that provided you ensure that any local labels used in a macro start
with '00' you can ignore the fact that a macro exists for the purposes
of local labels in the main code.
Similarly if expanded macros are 'nested' then any local labels defined
will be unique within that invocation and the labels in the 'calling'
macro will branch around labels in the called macro.
Remember that, like all non local labels, any other labels defined in
an expanded macro will become global and will assume the value assigned
in the current invocation.
Special features of Expanded macros
-----------------------------------
The most obvious advantage of expanded macros is that you can take
advantage of all the special features of SAsm when using them. The
ADRL, MOVL DB, DW and DD pseudo-ops can all be used if required.
You can call Macro Functions and other Expanded Macros can be invoked
from within macros. Expanded Macros can be 'nested' to a maximum depth
of twenty. In theory this could be greater, but I couldn't think of any
possible (non-contrived) circumstance when I would need more than four
or five so I limited it to twenty.
Expanded Macros must NOT be invoked recursively. This would obviously
set up an infinite loop which would cause all available memory to be
filled. This is another reason for limiting the nesting of macros
because if this is done by accident an error will be flagged before
this stage is reached.
Page 20
Example
-------
This is an example of how you could use a macro to print a string at
any location on the screen. Note that as usual I have used more spaces
than are actually necessary to make things clearer.
# SM print_tab x_pos , y_pos , display$
swi 256+31
swi 256+x_pos
swi 256+y_pos
swi "OS_WriteS"
equs display$
equb 0
align # EM
The operation of the code should be obvious. Firstly there is the
equivalent of 'VDU 31, x_pos, y_pos' to position the text cursor where
required. SWI "OS_WriteS" is then used to print the text which is
placed in memory immediately after it.
So, to print 'This is a test' at column 10, line 4 you would use
@ print_tab 10,4,"This is a test"
To illustrate nesting macros the following example splits this
procedure into two separate macros, one of which uses the other.
# SM do_tab x , y
swi 256+31
swi 256+x
swi 256+y
# EM
# SM print_tab x_pos , y_pos , display$
do_tab x_pos,y_pos
swi "OS_WriteS"
equs display$
equb 0
align
# EM
This would be used in exactly the same way as the previous example, but
note that as 'print_tab' uses 'do_tab' then 'do_tab' must be defined
before it can be used in 'print_tab'.
@ print_tab 10,4,"This is a test"
Would give the same results, and in this instance the code actually
assembled, would be exactly the same. In fact, it could be split still
more. Leaving the macro 'do_tab' as previously defined;
Page 21
# SM print_string string$
swi "OS_WriteS"
equs string$
equb 0
align
# EM
# SM print_tab x_pos , y_pos , display$
do_tab x_pos,y_pos
print_string display$
# EM
Once again exactly the same actual code would be assembled.
Errors in Expanded macros
-------------------------
SAsm will normally be able to recover from errors in expanded macros.
In this case the error message will be slightly different from normal
and in the form;
Error <error message> at line <number> in Macro <macro name> at line
<line number> in file <file name>
The line number in the file will be the line where the macro was
invoked. The line number within the macro will be the offset from the
start of the macro where the error occurred. If this was the invoking
line then the error will be shown as having occurred in line 0.
This can seem a bit strange if the macro invokes other macros. When the
error happens the macro has been expanded, so the line number may be
greater than the apparent size of the macro. For instance, in the final
example shown above if an error occurred in the line which invoked
'print_string' in the macro 'print_tab' the error would be shown as
having occurred not at line 2, but at line 5.
This is not normally a problem is practice because the actual error can
usually be discovered by inspection but I may improve upon it in a
later version.
Page 22
-=O=- MACRO FUNCTIONS -=O=-
General
-------
Macro Functions are defined and used exactly as in the Basic assembler.
If you don't know how this works I refer you to the 'Tutorial'.
Briefly a Macro Function is a Basic Function who's definition, as with
functions in a normal Basic program, must appear after the #END
directive. You use it by simply writing FN<name>, where <name> is the
name of your function, in your assembler source. Most Macro Functions
will require parameters and these are passed by being enclosed in
brackets after the function name in the usual way.
You must remember when defining a Macro Function that when it is called
you have quit the assembler and are back in 'normal' Basic. As a macro
will probably include assembly code statements you will need to use the
square brackets and define the OPT setting to re-enter assembler.
SAsm uses two variables to define the OPT setting, Q% and PASS. You can
therefore use either of these when defining Macro Functions. The only
time you need to depart from this is if you are using a forward branch
in the macro. In this case you will need to define a two-pass loop
within the macro and so you MUST define your own OPT variable. It is
therefore important that you should NOT modify or use in any way the
Basic Integer variable Q%. The only permitted use of this variable is
when you wish to see an assembler listing as previously described.
WARNING - You cannot use the SAsm 'extra' mnemonics DB, DW, DD, DIV,
ADRL, MOVL or the enhanced immediate 2nd operands in Functions. These
are ONLY available in the main body of the code or within Expanded
Macros before the #END directive. You can call functions FNadr, FNmov,
FNdiv and FNset as alternatives if required. These will be retained in
later versions for this purpose.
These restrictions will not be removed in later versions of SAsm since
whenever possible you are advised to use Expanded Macros instead.
The Built-In Functions
----------------------
SAsm has a number of pre-defined Macro Functions and the following
section describes them. Do not to use them in new work except when
called from within other Macro Functions as the extra mnemonics ADRL,
MOVL, DIV, DB, DW and DD should be used instead.
As well as the functions described there are two others FNadrc and
FNmovc. These should not be used directly and so are not documented but
do not create your own functions with these names or conditional ADRL
and MOVL will not work correctly.
Page 23
FNgap ( <size> )
----------------
Defines a gap in the code for use as a data area of <size> bytes. The
memory is not pre set to any value. If <size> is not exactly divisible
by 4 and you intend to follow FNgap with an opcode you should use ALIGN
to ensure that further assembly occurs on a word boundry. Use 'DB' for
preference unless within a Macro Function.
FNset ( <size>,<value> )
------------------------
Similar to FNgap except that the memory is preset to <value>. Use the
DB mnemonic in preference wherever possible.
FNadr ( <register>,<location> )
-------------------------------
FNadr is an expansion of the ADR pseudo-opcode. Its syntax is the same
except that the parameters must be enclosed in brackets. It can reach
any byte within 64K or within 256K if <location> falls on a word
boundry. If <location> is a forward reference FNadr always assembles
two instruction. If a backward reference FNadr assembles a single
instruction if possible and two only if absolutely necessary.
This is equivalent to the ADRL expanded mnemonic which should be used
in preference.
FNdw and FNdd
-------------
FNdw and FNdd (Define Word and Define Doubleword) are expansions of
EQUW and EQUD respectively. They preset consecutive words or double
words of memory with values passed as a comma separated list. The
syntax in each case is identical. FNdw like EQUW works with two byte
chunks or 'words' and FNdd like EQUD with four byte chunks or 'double
words'. As the Archimedes is a 32 bit computer a 'word' is really 4
bytes but I have retained the 'old' definitions to avoid confusion.
The full syntax is FNdx ( "<value>,<value>,<value>...." ) where <value>
is any valid number which can be placed in the memory location. For
example, to place the numbers 1 to 5 in 5 consecutive double words you
would use;
FNdd ("1,2,3,4,5")
Note that the list is passed as a STRING and so must be enclosed in
quotes. If more than about 25 numbers are passed in a single macro a
'Line Too Long' error may be generated. If you use FNdw and wish the
following code to be word aligned you should follow it with ALIGN.
Page 24
FNdb
----
At is simplest FNdb (Define Byte) is to EQUB what FNdw and FNdd are to
EQUW and EQUD. You can use it to simply preset a consecutive series of
bytes with values. However it also doubles as an equivalent to EQUS and
by combining the two into a single function makes it much simpler to
define strings of mixed text and control codes.
Like the two previous functions FNdb takes a string as it's parameter.
However in this case as well as comma separated values the string can
contain a 'string' enclosed in SINGLE quotes. For example;
FNdb ("7,'This is a beep.',13,10,'This is on a new line',13,10")
The normal equivalent of this would be
EQUB 7
EQUS "This is a beep"
EQUB 13
EQUB 10
EQUS "This is on a new line"
EQUB 13
EQUB 10
Naturally neither single or double quotation marks are permitted in the
string. If you wish them to appear in text you must use the ASCII code
as with control codes in the example above.
FNmov ( <register>,<value> )
----------------------------
This is an expansion of the MOV opcode to load a register with an
immediate value. Unlike the normal MOV this will generate sufficient
ADD opcodes after the initial MOV to load any 32 bit number. If <value>
is a negative number then MVN and SUB will be used. Note that when
using negative numbers you do not need to subtract 1 as you do with
MVN. eg. to load r3 with -123456 just use FNmov (3,-123456)
Use the MOVL mnemonic for preference unless within a Macro Function.
Page 25
-=O=- EXTRA MNEMONICS -=O=-
These are not actually mnemonics but are macros which are expanded by
the preprocessor. They are written into the code just like normal
opcodes and so this distinction can normally be ignored. One important
difference is that unlike normal mnemonics they must NOT have
conditional suffixes.
Some of them call the built-in macro functions and reference should be
made to these for further clarification if required.
They may all be written in upper or lower case like normal assembler
mnemonics.
DW and DD
---------
These are expansions of the normal EQUD and EQUW codes and in fact are
translated into these when expanded. The main advantage is that DW and
DD can be used to reserve a series of words or double words and not
just one at a time. These follow the mnemonic as a comma separated
list. For example -
DD 1,2,3,4,5,6
would be expanded by the preprocessor to -
EQUD 1:EQUD 2:EQUD 3:EQUD 4:EQUD 5:EQUD 6
which can save a lot of typing.
Because the line will actually become longer, which is obvious from
looking at the above example, it is possible for these codes (and the
DB mnemonic which follows) to cause the line to expand beyond the
permitted limit of 255 characters. You should therefore avoid putting
too many items on a single line.
If any of the numbers begin with a zero SAsm will assume that the
number is in hex format, whether or not it is preceded by an '&'
character. for example '20' would be decimal 20 but '020' would be
translated as &20, eg. hex 20 which is decimal 32.
Page 26
DB
--
This is a general purpose macro which replaces the EQUB and EQUS
directives and also allows an area of memory to be reserved for data
and preset to any value if required.
In it's simplest form DB acts exactly like DW and DB but with byte
sized sections as a multiple EQUB. However if the parameter is a string
enclosed in double quotes it acts like EQUS. These can be mixed in the
same DB macro which makes defining strings mixed with control codes
much easier. For example -
DB 7,"This is some text",10,13,"A new line",0
would be expanded to -
EQUB 7:EQUS"This is some text":EQUB 10:EQUB 13: EQUS"A new line":EQUB 0
As with DW and DD beware of allowing the line to become too long.
Again numbers beginning with a zero will be regarded as hexadecimal.
DB can be used with a multiplier to reserve an area of memory and set
it to any value. If a parameter begins with '*' then the following
number is taken as a multiplier and the number after that as the value
to be inserted. For example -
DB *100,32 (which could also be written as DB *100," " )
would reserve the next 100 bytes of memory as a data area and load them
with the value 32, a space character.
This can be mixed in with strings and single bytes and can be used
rather like SPC or STRING$ in Basic.
For example -
DB "1",*10,32,*8,".",*10,32,"First Menu Item",0
would be expanded to the zero terminated string -
1 ........ First Menu Item
One advantage of this is that the multiplier need not be an actual
number but could be an expression. This makes it a lot easier to change
the size of data areas or the length of strings by simply altering the
value of the variable.
If you just wish to reserve an area of memory and do not need it to be
set to any particular value then using a question mark as the value
after the multiplier will do so. For example
DB *100,?
would reserve 100 bytes but leave the area set to whatever random data
already existed there.
Page 27
ADRL
----
This is a two instruction 16 bit ADR directive. It takes the same
parameters as the normal ADR directive, that is the syntax is -
ADRL <register>,<location>
ADRL will always assemble two instructions when <location> is greater
then the current address. This is because the exact position of
<location> will not be determined until the second pass. However if
<location> is before the current address it's position will already be
known and so a single instruction will be assembled whenever possible.
If code length or speed is important you could use the ADR instruction
until you get an 'out of range' error to ensure that no superfluous
instructions are included.
Note that there MUST be a space between ADRL and <register> and that
the it CAN now be made conditional
MOVL
----
This is a method of loading a large immediate number into a register. A
series of ADD or SUB instructions will be assembled to load the value.
The syntax is MOVL <register>,<number>. If <number> begins with a zero
it will be regarded as hexadecimal. <number> can of course be positive
or negative. If it is negative then MVN instructions may be used by the
macro but DO NOT adjust the number to allow for this as is required by
the normal MVN instruction. The macro will make all the adjustments
necessary so just write the actual number you require.
This macro is fairly simple and does not always produce the most
efficient code for loading a given value. If speed or code length is
paramount it may often be possible to reduce the number of operations
by hand coding.
Note that there MUST be a space between MOVL and <register> and that it
CAN now be made conditional
Page 28
DIV
---
--** DIV is not included in the Unregistered version of SAsm **--
This macro will perform a 32 bit integer division. The full syntax is;
DIV <dividend reg>,<divider reg>,<quotient reg>,<temp reg>
It therefore requires four DIFFERENT registers as its parameters and
you are responsible for loading the correct values into the registers
before using DIV. The results returned are;
<quotient reg> = <dividend reg> DIV <divider reg>
<dividend reg> = <dividend reg> MOD <divider reg>
The <temp reg> is used for working only and will be corrupted.
For example, to divide a number in R0 by a number in R1 and return the
result in R2 using R3 as temporary workspace use;
div r0,r1,r2,r3
On exit r1 will be unchanged and r0 will contain the remainder if the
number did not divide exactly.
Note that there MUST be a space between DIV and <register> and that
because it expands to a large section of code it CANNOT be made
conditional.
Page 29
-=O=- ENHANCED 2nd OPERAND -=O=-
This operates on the second operand of instructions CMP, MOV and TEQ.
It will work whether or not the instruction is conditional but it can
NOT be used with CMN or MVN (yet!). For it to work there must be a
space between the opcode and the first operand.
The aim is to make it easier when the second operand is an immediate
value rather than another register. The Basic assembler requires the
second operand to have a leading '#' character for it to be recognised
as an immediate value. SAsm will accept this but will also recognise
most immediate numeric operands.
If the second operand begins with a digit 0-9, an '&', a '%' or is
enclosed in double quotation marks SAsm will assume that it is an
immediate value whether or not it is preceded by '#'. There is also no
need to use the Basic 'ASC' prefix if a character is enclosed in double
quotation marks. For example -
SAsm Basic Assembler equivalent
cmp r0,"A" cmp r0,#ASC"A"
mov r0,020 mov r0,#&20
mov r2,"z"+1 mov r2,#ASC"z"+1
mov r2,1+"z" !Error - won't recognize "z" as an ascii value
cmpne r0,13 cmpne r0,#13
teq r0,"m" teq r0,#ASC"m"
cmp r0,%110 cmp r0,#%110
mov r0,&A4 mov r0,#&A4
mov r0,0A4 mov r0,#&A4
mov r0,A4 !Error - A4 won't be recognised as an immediate number
As you can see this makes the code easier to read and also avoids
strange errors when you forget to include the '#'.
Note that you can ONLY use these shortcuts when the number is obviously
an immediate value. If it is a variable you must still use the '#'.
WARNING - Because a number in the second operand position will always
be regarded as an immediate value if you really DO mean a register you
will have problems. For example, the instruction 'mov 1,3' would be
interpreted by the Basic assembler as 'copy the contents of register 3
into register 1' but by SAsm as 'load register 1 with the immediate
number 3'.
To avoid this sort of ambiguity it is usual when writing ARM code to
always prefix register numbers with 'r' or 'R', but this is not
compulsory and the Basic assembler doesn't require it. If you have
fallen into bad habits and just use a simple register number then you
will have problems. There are two possible solutions. Firstly you could
mend your ways and refer to registers properly like everyone else.
Secondly you could write to me and I might include an assembler
directive to instruct SAsm not to use the second operand enhancements.
Page 30
-=O=- LABELS -=O=-
Global Labels
-------------
All labels are common throughout all the files. It is important to
remember this or some very strange things can happen. With SAsm you
don't need to declare labels as 'global', they are ALWAYS global.
Adding the suffix 'X' to the command line invokes the label cross
reference function. This will check all labels and report any multiple
definitions.
For reasons previously explained multiple definitions of a label are
classed as Warnings only and not Errors. If like me you repeatedly use
labels like 'loop' or 'back' to form short loops you will need to
visually check the list of duplicates for 'foreign' names. To make this
easier it is best to press CTRL-N when typing the SAsm command line.
This will stop the screen scrolling until you press SHIFT. When I get
time I shall include a routine to write the duplicate label list to the
Error File so you can examine it at leisure.
Local Labels
------------
Since it could become tedious to invent names for all the labels you
need to make short jumps and loops a system of 'Local Labels' has been
included. These are defined in exactly the same way as normal labels,
ie. by preceding the label with a full stop. Local labels MUST be
defined at the start of the line, which is good practice anyway, and
consist of a two digit decimal number 00-99.
Local label scope
-----------------
You start each 'set' of local labels with a label '00' When SAsm finds
label 00 if 'forgets' all previous local labels. You can therefore use
the numbers 00 to 99 repeatedly and each local label will only apply
within its own section. Each time you start a new section of code or
sub-routine make the first label in that section 00 You can use label
00 even where it is not necessary to ensure that the scope of the
current set of local labels is ended.
You will soon find that you will use local labels for all the loops and
short jumps in a section, using meaningful labels where appropriate.
This makes the code much easier to follow because the 'real' labels
which define entry points and complete routines stand out.
Local labels can ONLY be used with Branch (or BL) instructions, with or
without conditions, and with the ADR or ADRL pseudo-opcode. They cannot
be used within Macro Functions.
Page 31
Local Label Example
-------------------
Any Branch instruction will only reach back to the last 00 label and
forward to (but not including) the next. The following example should
make this clear.
.00 ........ ; some code
........
........
.01 ........
........
.02 BNE 01 ; This will branch BACK to the last 01
........
........
.00 ........ ; This starts a new section of labels
BGT 01 ; Branch FORWARD to 01 in this section
........
.01 ........
BEQ 02 ; This will produce an error as 02 is not
........ ; defined in this section
BLT 00 ; Branch BACK to the last 00
.00 ........ ; Start another section
ADR r1,00 ; Put address of the LAST 00 in R1
ADR r2,01 ; put address of the NEXT 01 in R2
........
.01 ........
The maximum number of 'sets' of local labels allowed is 2700 sets,
which should be enough for any eventuality.
Forward branch to 00
--------------------
Consider this short piece of code;
cmp r0,#32
bne 00
........ ;code to be skipped if r0 not 32
........
.00 ........ ;rest of code
This won't work. The branch would go BACKWARDS to the last 00. You can
NEVER branch FORWARD to a 00 label. You must insert a 'dummy' label
somewhere before the branch instruction to 'reset' the local label
system. The correct way to write the previous example is;
.00 cmp r0,#32
bne 01
........ ;code to be skipped if r0 not 32
........
.01 ........ ;rest of code
The 00 label is not used but it resets the local label system so that
the branch is correctly interpreted.
Page 32
-=O=- THE MACRO LIBRARY -=O=-
--** This facility is available only to REGISTERED users **--
Using the Macro Library
-----------------------
The Registered version of SAsm can record every Macro Function or
Expanded Macro call in your source file.
If it is an Expanded Macro and it has not been previously defined
somewhere in your code then it can be loaded from a special Library
file and inserted in the source.
If it is a Macro Function it will be checked against the definitions
found after the #END directive. If one or more definitions cannot be
found it will try to load the missing definitions from a Library file.
For Macro Functions the Library is only checked after all the source
files have been loaded so a Macro Function in a source file will
'override' a macro of the same name in the Library.
If an Expanded Macro is defined in the source file it will be used in
preference to one of the same name in the Library. If a macro is
defined part way through the source files then any calls to that macro
before it is defined will be loaded from the Library and those after
will use the version in the source file.
The 'L' parameter
-----------------
If you are using a hard disc this operation is so fast that the only
way you know it is happening is that SAsm will tell you that it is
loading Macro Functions or that the Library isn't required. If you are
using a single floppy drive you may have your Library file on another
disc. When you know that no Library macros are required it is annoying
to have to change discs and allow SAsm to satisfy itself that the
(probably misspelt) missing Macro isn't in the Library. You can
therefore add the suffix 'L' to your command line to tell SAsm NOT to
use the Library, even if SAsm$Lib (see later) is defined.
Use of the 'V' parameter
------------------------
If you have used the 'V' (verbose) parameter then as each Expanded
Macro is being searched for a message is displayed. Normally this takes
the form -
Searching Library for Macro <macro name> - Loaded
But if the macro cannot be found in the Library it will say -
Searching Library for Macro <macro name> - Not found in Library
At this stage a missing macro will not be classed as an error but it
will become one during assembly because the macro will be missing.
Page 33
The SAsm$Lib OS variable
------------------------
To tell SAsm that a Library exists you should either create an OS
variable 'SAsm$Lib' with the path/file name of the Library or use the
#LIB directive within the source file. To use the SAsm$Lib variable
type at the OS '*' prompt 'Set SAsm$Lib <filename>' where <filename> is
the path/file name of your Macro Library or put this command in your
!Boot file. You can of course have more than one Macro Library and just
change SAsm$Lib to refer to the one in current use.
When SAsm can't find a macro definition in the source files it has
loaded it will check to see if a Library has been defined. If it is it
will extract the 'index' which MakeLib has created. This will be
checked against any missing definition and if these appear in the
Library they will be included.
If SAsm can't find the definition of a macro in the source files and
the 'L' parameter hasn't been used but a Library hasn't been defined
then an Error message will be displayed. If you are sure that all the
required macros exist in the source it is best to use the 'L' parameter
to ensure that this doesn't happen.
Preparing a Macro Library
-------------------------
First create a source file of Macro Functions and/or Expanded Macros.
These are macro definitions definitions exactly like the ones you would
normally use in your source files.
Each Expanded Macro should begin with the #SM directive and end with
the #EM directive.
In earlier versions of SAsm it was stated that each Macro Function
definition should end with an '=' as the first character on a line but
this is no longer required.
On your program disc you will find an application called 'MakeLib'.
Copy this to a blank disc and *MOUNT the disc or copy it to the Library
directory of your hard disc. Now at the OS '*' prompt type;
*MakeLib <source filename> <Library filename>
where <source filename> is the full path/file name of your Macro
definition file and <Library filename> is the path/file name that you
wish to call the actual Library file that SAsm will use.
MakeLib will load your Macro source file and prepare it for use by
SAsm. Once MakeLib has created the Library file the original source is
no longer required but you should of course keep it so that you can add
new macros and update your Library in the future.
The present version of MakeLib can only accept a single source file but
I intend to improve it to accept wildcards in a similar manner to SAsm.
Page 34
Length of Library file
----------------------
The source for your Library file can be any length and can have as many
comments ay you like. As with normal SAsm source files these will all
be stripped before the routines are added to the actual Library.
The Library file can hold about 200 Macro definitions which should be
enough for anyone. I suggest that in practice you only put the macros
you frequently require in your Library and use INCLUDE files for those
only rarely needed. This will make the search time shorter and also
probably allow you to put your Library on your normal working disc if
you are using a single floppy.
Page 35
-=O=- SASM AND THE DESKTOP -=O=-
SAsm was originally intended to be used for the OS command line prompt.
However the introduction of good text editors such as !Zap and other
tools now make it possible to to develop programs within the Archimedes
desktop. Although SAsm is still not integrated into the desktop
environment Versions after 1.40 have features which help them to be
used in this way.
The new features
----------------
The changes which have been introduced are described in the section on
directives. They enable all of the parameters which previously had to
be typed at the command line (and more) to be inluded in the file as
Directives. This should mean that only the name of a single 'make' file
needs to be typed and this file can contain all other data needed to
assemble the program. The next step is to write a desktop 'front end'
for SAsm which will enable programs to be assembled within the desktop
in a similar manner to Acorns (unbelievably expensive) DDE and this
will be appearing soon.
Even without the 'front end' you can now use SAsm within the desktop
very easily and assemble projects by clicking on a single 'Obey' file.
You will not now need to set the CSD as you will be able to use the
<Obey$Dir> OS variable to define the 'start point' of your project
directory structure.
Using SAsm from the Desktop
---------------------------
Ou can now include everything needed to assemble an extensive project
in a single short 'make' file. This would normally be a text file and
will contain all the preliminary directives (org, size, type, etc) plus
directives to define the object and error filenames and the library to
be used. Following these will come a list of Include files to be
assembled.
The main advantage of this system for desktop use is that it enables an
Obey file to run SAsm. For example, to assemble a desktop project you
should set up a directory structure as shown.
root
|
|
----------------------------
| |
source !app
The 'root' directory would contain your 'make' file and the Obey file
which will run it. It need not, of course, be the actual root directory
of a disc, it is just the root directory of your project. The !App
directory will be the RiscOS application directory for your project.
The 'Source' directory will contain all of your source files. You
could, of course, also have other directories to hold special library
files, error files, notes, etc. if required.
Page 36
Assuming the Make file is simply called 'Make' the Obey file would
contain just two lines -
Set Project$Dir <Obey$Dir>
Sasm <Project$Dir>.Make
When you double-click on this file it will atomatically create an OS
variable 'Project$Dir (or whatever you want) and set it to 'Obey$Dir',
ie. to the 'root' directory of your project. It will then Run SAsm
(either from the RMA if you have loaded the Module version or from
disc) with the filename of the Make file.
The Make file should define the various parameters to assemble the
program using the <Project$Dir> variable. Alternatively you could set
the OS variable using the CLI directive from within the Make file. It
would also contain directives to define the error file, library and
object file, for example -
# errfile <Project$Dir>.err
# obj <Project$Dir>.!App.!Runimage
and the files to be assembled would be -
# include <Project$Dir>.source.first_*
# include <Project$Dir>.source.second_*
# include <Project$Dir>.source.third_*
or whatever they are called. Note that you can still use the
'descending trailing digits' wildcard to assemble the latest version.
Your Make file need not, of course, be in the 'root' directory, it
could be in the source directory if you prefer, (it is, technically,
just another source file).
If you don't have a hard disc you will probably prefer to have your
source files (and certainly the error file) on the RAM disc. As SAsm
doesn't create any temporary files you don't need much spare space.
To assemble a project in this way just double-click on the Obey file.
You will have to wait for the new 'front end' to have messages trapped
in a desktop window, at present they'll just appear in a Command
window. You can, of course, use SAsm in a 'Task' window but this means
you will need to define directories and type filenames again.
IMPORTANT
---------
I'm continually trying to improve SAsm. PLEASE tell me if you have any
problems, even if you haven't registered. It's only by acting on your
bug reports and suggestions that I can continue to improve SAsm.
If possible send a copy of the source code that cause the problem,
preferably all the files, not just the one that caused the error, plus
any error files generated or any other information. Especially I need
to know exactly how the program failed, 'it wouldn't work with this'
isn't very helpful!
Page 37
-=O=- PROBLEMS and QUESTIONS -=O=-
The questions I am most often asked about SAsm are 'what language is it
written in?' and 'how fast is it?'.
These two questions can most easily be answered together. SAsm is
written in machine code using SAsm. Each version is assembled using the
previous version. The source code is then changed to take advantage of
any new features and re-assembled. I therefore test SAsm by 'self
assembling' the distributed version.
The source for SAsm consists of more than 4000 lines split over eight
files. These are loaded from disc, assembled, and the source file saved
to disc in less than six seconds on an A400 series using an ARM 2
processor or about two seconds on an A5000. I think this is fast enough
for most purposes. Naturally if you didn't have a hard disc the time
taken would be quite a bit longer but as SAsm can easily use a RAM disc
this shouldn't be a serious problem unless you are trying to write long
programs on a 1Mb machine. Unlike most assemblers and compilers SAsm
doesn't use much memory for its own purposes.
At present SAsm is entirely Command Line driven and doesn't have a
desktop 'front end'. There is no reason why this can't be done. As soon
as I feel that the basic program is 'stable' I shall write one so that
you can work entirely within the desktop if you wish.
There are a couple of 'features' of SAsm which can cause trouble. Some
are minor bugs which are not important once you know about them and
will be fixed when I have time. Others are errors which can occur
because of changes in the syntax used by SAsm. I will record some of
the queries which have been raised by users in the hope that it will
avoid others experiencing the same problems.
1. There MUST be a space between the mnemonic and the first operand for
many of SAsm's functions to work correctly. This is not always
essential with the Basic assembler but it is good practice so I make
no apologies for it.
2. MOVL, ADRL and DIV are actually macro's and not assembler mnemonics.
ADRL and MOVL can be made conditional but because DIV expands to
several lines of code with internal compare instructions it cannot.
3. Make sure that you have started every set of local labels with '00'.
4. You cannot use local labels, DB, DW, DD, ADRL, MOVL, DIV or any of
the enhanced second operator functions after the #END directive,
This means you can't use them within Macro Functions. You can,
however, use them within Expanded Macros because these are defined
before the #END statement.
5. Because DB, DW and DD instructions may expand considerably they can
cause a 'line too long' error if you put too much on one line.
Page 38
6. SAsm removes redundant spaces and comments as it is processing a
file but other operations expand it. Normally the contraction is
greater than the expansion so the file shrinks. As each file is
loaded a 16K 'overhead' is allowed in case the file does grow.
Normally this is adequate but in extreme cases of large individual
files and no redundant spaces and comments the program could crash.
I will add functions to guard against this when I get time but I do
not regard it as a serious fault because the whole purpose of SAsm
is to enable you to split up and spread out your source files.
7. Because SAsm regards a ';' as defining a comment if you insert a
line of Basic which has a PRINT statement that includes the ';'
character with a preceding space it will be 'cut off'.
8. At present there must be a CR or LF at the end of each file. Once
again I will correct this when I get time.
9. It is possible for the program to abort giving an error message with
a line number which is much greater than the length of the file in
which the error occurred. This normally means that the error
actually occurred inside a Macro Function. This is always a problem
with Basic Functions and Procedures and there is no simple solution.
Often the only way of discovering the actual error is to examine
every FN call in the file in which the error occurred.
10. SAsm can abort with an error if there is not enought space for line
numbers. This is because after SAsm has finished with the files
Basic will need to add 3 bytes to each line for the line number and
length byte. The only solution is to make more memory available.
Page 39
-=O=- RELEASE HISTORY -=O=-
1.0 Oct. 91 First release
1.1 Nov. 91 Functionally as 1.0
Bug fixes
X-ref and Macro Library functions re-written
and much faster, delays now imperceptible
with hard disc.
1.2 Nov. 91 Bug fixes
Much improved error handling
INCLUDE directive added
1.21 Jan 92 Restrictions on INCLUDE directive with
Shareware version removed.
1.22 Mar 92 Improved error handler
1.23 May 92 Minor bug fixes
1.24 June 92 Line numbering system rewritten, dramatic
speed increase for large files
Line number space relocation added
1.25 July 92 adrl, movl, div, db, dw, dd, added
enhanced immediate 2nd operand
1.26 Feb 93 Bug in adrl in some examples of 1.25 fixed.
No public release of this version.
1.30 Mar 93 Expanded macros introduced.
db *xx,? to reserve area without setting
New Makelib tool for expanded macros
Module provided so SAsm can now be run from
the RMA for floppy disc users.
1.31 Apr 93 ADRL and MOVL can be conditional
1.32 Jun 93 Bug fixed in expanded macro stack.
1.41 Aug 93 #obj, #lib, #errfile, #cli, #verbose, #quiet,
#xref and #noxref directives introduced.
Tab characters accepted as delimiters.
1.42 Sep 93 Bug with DB, DD and DW in upper case fixed.
Bug with comment on Macro call line fixed.
'Line Too Long' trapped during preprocessing
1.43 Oct 93 Bug with DB, DD and DW in upper case fixed.
(Honest, it's fixed, really....)
Registration Form for SAsm
Please complete this and post it with your cheque for Eight Pounds to;
David Holden, 39 Knighton Park Road, Sydenham, London SE26 5RN
____________________________________________________________________
Name and Address:
____________________________________________________________________
Where did you obtain SAsm:
____________________________________________________________________
Have you had any problems:
____________________________________________________________________
What additional features would you like: