Pfad: Home =>
AVR-Assembler gavrasm => Introduction
Here I introduce some special features of the gavrasm Assembler. These examples
do not compile on other assemblers. The features discussed:
- Calling the assembler on a command line
- Calling the assembler within a batch or a shell
- Window caller as assembling tool
- Using the IF-ELSE-ENDIF directive
- Use of the EXIT directive
- Using macro labels
- Using special literal constants
- Using a separator in constants
Assembling with gavrasm on the command line is as follows.
- Open a command line (Win: select start/programs/addons/MSDOS window) or a
shell (Linux-KDE) and change the directory, typing cd [path], to the one that
has the source code file.
- Assembling starts with typing [gavrasm-path]gavrasm [-options] sourcefile[.asm].
If you have all used INCLUDE-files in the same directory where the source code
file resides, you can just add the name of these files (e.g. .INCLUDE "8515def.inc").
Otherwise add the whole path to the included files (e.g. .INCLUDE
"C:\avrtools\appnotes\8515def.inc" or "/home/gerd/avrasm/def/8515def.inc").
The parameter options are completely listed in the file ReadMe.Txt. Here are
some additional explanations:
- Option -a makes sense in Linux, if you have no ANSI chars in your command line
shell or if you do not like displaying line numbers in that shell. -a switches the
output of linenumbers off (as is default in the win version of the assembler).
- Option -b makes sense for beginners to get extended error messages. The error
message then comments the required parameters of an instruction. This works only
if you have chosen longer error messages with the -e option (e.g. -eb).
- Option -l switches the generation of the list file off. That makes sense only
if you don't have enough disk space.
- Option -q suppresses the output of error messages on the command line. The
only messages then are INCLUDEs, the pass information and the result of the
compilation (number of errors).
- Option -s switches the output of the symbol list in the list file on, as far as
listing is not switched off. All symbols are displayed at the end of the list file,
sorted by the type of the symbol:
- R: Register,
- L: Label,
- C: EQU-constant,
- V: SET-variable,
- M: Local macro-symbol (label in a macro),
- G: Globalized macro-label
Additional informations listed are how often the symbol was redefined (nDef), how
often the symbol is used (nUsed) and the last value of then symbol in decimal and
hex form.
- Option -w allows wrap-around. These are jumps or branches forward (over the
end of the adress space to its beginning) or backward (over the beginning of the
adress space at its end. This option makes sense, if the AVR has a 4k flash, which
isn't accessible by relative jumps or branches. Wrap-Around in gavrasm does also
work with the relative brach instructions like BRCC or BREQ. Because other assemblers
do not allow this, this source code will only compile correct with gavrasm.
- The options -?, -h, -d and -t will set the assembler to only output the required
information (-? and -h: list of options; -d: list of implemented directives; -t:
valid AVR types and their properties). An added source code file name on the command
line is ignored!
To the top of that page
If you're tired of typing in the path of the assembler, you can place that
call in a batch file. If win is used: create a new textfile in the same
directory, where your source resides, and add the following lines:
REM Batch calling assembler
[drive]:
CD [Path-to-your-sourcefile]
[gavrasm-path]\gavrasm [-options] sourcefile[.asm]
PAUSE
Rename this text file with the extension ".bat". If you like, you can place a
reference to that batch file on your desktop. Assembling is just started by
clicking on that file or its reference. PAUSE leaves the window open, until
you type in a character.
In Linux we use the follwing shell script:
cd [Path-to-your-sourcefile]
[Path-to-gavrasm]/gavrasm [-options] sourcefile[.asm]
read key
and place it somewhere with the extension .sh. Those who like it: place a reference
to that shell on the KDE desktop (Create new, reference to program, execute
in a terminal program). The line with "read key" leaves the shell open.
To the top of that page
Tired of writing batch files for the command line assembler, if you
work in a window-orientated environment? Here's something for you!
By request I designed a windows program that creates batch files, calls the
assembler, and allows views/editing for the different textfiles that play a role
in assembling. Some new features are:
- It is menue-driven and allows working with whole projects.
- Settings can be saved and loaded, for a quick change of the project.
- It includes an editor for the source files.
- In its current form the editor displays row and column information (unlike
most simple windows editors) and allows tab characters in the files.
- Recognizes any include files automatically and allows editing. Includes
can be nested, a maximum of five include files can be handled.
- If you open the list file after assembling, you can quickly find
errors, load the responsible files and edit the line directly.
The Read-Me file has more informations
on its features and how to work with that small helper.
This executable is only available for windows operating systems
(sorry linuxers). The zipped executable and the ReadMe-file is
available for downloaded here.
The additional directives .IF, .ELSE and .ENDIF add the opportunity to compile
or not compile certain code depending on conditions. During compilation the IF
condition is checked. If it is true, the following source code is compiled. If
not, the compilation is restarted behind the .ELSE or the .ENDIF directive.
Be careful: If those two directives are missing, the whole remaining source code
might not be compiled!
As application example the following source code:
.EQU clock=40000000
.IF clock>4000000
.EQU divider=4
.ELSE
.EQU divider=2
.ENDIF
A short look to the symbol list in the list file shows, that divider has been
set to 2. If you change the value of clock e.g. to 10,000,000, divider will
be set to 4. Generally speaking: you can avoid further changes in the source
code, if you anticipate these changes under certain conditions.
A typical application is, if you like to write and use the same code for
different processor types. With other types, interrupt vectors are different.
Using .IF, the vector area of the processor is compiled specifically for each
AVR type.
;
; Define processor type on top of the source code
;
.EQU aType=2313 ; Processor is a 2313
;.EQU aType=2323 ; Processor would be a 2323
;.EQU aType=8515 ; Processor would be a 8515
;
; Int-Vector area
;
.CSEG
.ORG $0000
rjmp Main ; for all types
rjmp IntVecInt0 ; External Int Vector, is used
; Int-Vector area for 2313
.IF aType == 2313
reti ; IntVecInt1 ; External Int Vector, not used
reti ; Timer1Capt, not used
reti ; Timer1/Comp, not used
reti ; Timer1/Ovf, not used
rjmp IntVecTC0Ovf ; TC0-Overflow, used
reti ; UartRX, not used
reti ; UartUdre, not used
reti ; UartTx, not used
.ENDIF
; Int-Vector area for 2323
.IF aType == 2323
rjmp IntVecTC0Ovf ; TC0-Overflow, used
.ENDIF
; Int-Vector area for 8515
.IF aType == 8515
reti ; IntVecInt1 ; External Int Vector, not used
reti ; Timer1Capt, not used
reti ; Timer1/CompA, not used
reti ; Timer1/CompB, not used
reti ; Timer1/Ovf, not used
rjmp IntVecTC0Ovf ; TC0-Overflow, used
reti ; SpiStc, not used
reti ; UartRX, not used
reti ; UartUdre, not used
reti ; UartTx, not used
reti ; AnaComp, not used
.ENDIF
;
; Interrupt-Service-Routine INT0
;
IntVecInt0:
[...]
reti
;
; Interrupt-Service-Routine TC0-Overflow
;
IntVecTC0Ovf:
[...]
reti
;
; Main program start
;
Main:
[...]
You see, that just changing the processor type is easy, if you have once
designed the vector area for this type. Otherwise you'd have to go through
your whole source code and redesign. If you forget the difference in the
int vector area, you run into a real nice design bug.
The conditions of the .IF directive can be more complex, if you like, e.g.:
.IF (aType == 2313) || (aType == 8515)
Nested .IF directives are currently not implemented in order to keep the
thing simple.
To the top of that page
If a certain number exceeds its defined value range, one likes to stop
assembling and issuing an error message. So, if you missed this opportunity
for extended range check in other assemblers, you'll be a friend of gavrasm.
.EXIT checks the following condition and stops assembling, if it's true:
.EQU clock=4000000
.EQU divider=64
.EXIT (clock/divider)>65535
With this range check you make sure that no overflow of your 16-bit
timer/counter will occur, before you run into a debugger problem. gavrasm
notifies you of such a condition and refuses compilation of the buggy code.
To the top of that page
Macros are code sequences stored by the assembler, which are only added to the
code, if the macro is called. E.g.:
.MACRO mtest
.nop
.ENDM
;
; Here we place the macro's code
;
mtest
The code within the macro can be changed by calling the macro with paqrameters.
Parameters can be numbers, but can also be register names or any other symbol.
The parameters are referenced within the macro as @0 bis @9. E.g. like this:
;
; Register global definition
;
.DEF rmp,R16
; Here's the macro
.MACRO mtest
ldi @0,@1 ; Expects a register as first param, a constant as second
clr @0
.ENDM
;
; Macro call with parameters
;
mtest rmp,50
The use of macros in gavrasm is enhanced, because you can call macros within
a macro whenever you need it. Nesting of macros is only limited by memory
storage space.
Labels in macros are in gavrasm clearly protected. Labels can only be used
within the macro, using them outside the macro yields an error message. This
prevents bugs, if you call a macro more than one time in your source code.
Globally defined symbols are accessible within the macro, so don't try to
use a symbol name in a macro, that is already defined outside. If you'd like
to export a local label within a macro to the outside, use the special
directive
.SETGLOBAL label1[, label2, ...]
to export its value. Whenever you call such a macro, the value of label1 is
redefined to its current value. This works exact, even if the label is used
before it is defined.
With this instrument I added the opportunity to write extensive code for
different purposes in macros, and place these code sequences into the source
whenever it is required. As the code is only placed there if the macro is
called, you can include all your favoured macros, without wasting place if
you don't need some of them.
To the top of that page
gavrasm allows the use of ASCII control codes within a literal constant, e.g.
.DB "This is the first line.\m\jThis is the second line."
A '\'-char is inserted by two backspaces, e.g. "path is C:\\dos". Contrary to
other assemblers, a ';' in a string is recognized and treated correct.
To the top of that page
gavrasm allows the use of the dot as separator in constants, e.g.
.EQU abc = 0b0001.0010
.EQU def = 0x0FFF.FFFF
Don't ever try to assemble this code with another assembler!
To the top of that page
©2003 by
http://www.avr-asm-tutorial.net