gasp
preprocesses each INFILE argument and concatenates the results to
standard output, for direct consumption by as(1).
Since as is targeted to assemble the output generated by other
programs, it doesn't have common facilities such as macros or conditionals
that are generally useful when writing assembler by hand. gasp
provides this missing functionality.
OPTIONS
-a, --alternate
Use alternative macro syntax.
-c CHAR, --commentchar CHAR
Use CHAR as the comment character. The default comment character
is `!'.
-d, --debug
Show debugging statistics. This option produces statistics about the string
buffers that gasp allocates internally For each defined buffersize
S, it shows the number of strings N that it allocated, in the
format
strings size S : N
These statistics are written to standard error stream, when done
preprocessing.
-o OUTFILE, --output OUTFILE
Write the output generated by gasp to OUTFILE. The default is
to write to standard output.
-p, --print
Print commented line numbers. No effect if -s is not specified.
-s, --copysource
Print commented source lines.
-u, --unreasonable
Bypass "unreasonable expansion" limit. Since you can define gasp
macros inside other macro definitions, the preprocessor normally
includes a sanity check. If your program requires more than 1000
nested expansions, gasp normally exits with an error message. Use
this option to turn off this check, allowing unlimited nested expansions.
-h, --help
Print a usage message on standard output and exit successfully.
-v, --version
Print version information on standard output then exit successfully.
PREPROCESSOR COMMANDS
Commands are case-insensitive, and each extends for a line divided in three
fields: an optional label, the command itself, and optional argument(s) to
the command.
Conditionals
These directives allow you to include or exclude portions of assembly
depending on how a pair of strings or absolute expressions compare.
.AIF ARG1 CMP ARG2
.AIF ARG1 CMP ARG2
Available CMP comparision operators available with strings and absolute
expressions:
EQ
Are ARG1 and ARG2 equal?
NE
Are ARG1 and ARG2 different?
Available CMP comparision operators available with absolute
expressions only:
LT
Is ARG1 less than ARG2?
LE
Is ARG1 less than or equal to ARG2
GT
Is ARG1 greater than ARG2?
GE
Is ARG1 greater than or equal to ARG2?
.AELSE
Marks the start of assembly code to be included if the condition
fails. Optional, and only allowed within a conditional (between
.AIF and .AENDI)
.AENDI
Marks the end of an .AIF conditional block.
Loops
These directives allow you repeat portions of code.
.AREPEAT EXPR
.AENDR
Repeats the assemby code between the .AREPEAT and .AENDR macros
as many times as specified by the absolute expression EXPR.
.AWHILE ARG1 CMP ARG2
.AENDW
Repeats the assembly code between the .AWHILE and .AENDW macros
as long as the CMP conditional comparision holds true. The format for
CMP is the same as for .AIF.
.EXITM
Break out of the loop.
Variables
Variables can represent strings, registers or the results of expressions.
There are two kinds of variables:
* Variables defined with .EQU or .ASSIGN. To evaluate this kind
of variable in your assembly output, simply mention its name. These
variabes are only evaluated when writing the assembly output, so they
shouldn't be used in conditional expressions or .AWHILE loops.
foo .EQU FLIP-64
bar: .EQU FLIP-64
mov.l foo, r0
* Variables for use during preprocessing, defined with
.ASSIGNC or .ASSIGNA.
To evaluate this kind of variable, write `\&' before the variable name.
opcit .ASSIGNA 47
.AWHILE \&opcit GT 0
.AENDW
Macro arguments are treated almost the same way, but to evaluate them you
use the prefix `\' rather than `\&'
PVAR .EQU EXPR
Assign preprocessor variable PVAR the value of the expression
EXPR. There are no restrictions on redefinition.
PVAR .ASSIGN EXPR
Almost the same as .EQU, save that you may not redefine PVAR.
PVAR .ASSIGNA AEXPR
Define a variable with a numeric value, for use during
preprocessing. AEXPR must be an absolute
expression. There are no restrictions on redefinition.
PVAR .ASSIGNC STR
Define a variable with a string value, for use during
preprocessing. There are no restrictions on redefinition.
PVAR .REG (REGISTER)
Define a variable that represents a register. In particular, REGISTER
is not evaluated as an expression. There are no restrictions on
redefinition.
All these directives accept the variable name in the "label"
position, that is at the left margin. You may specify a colon after
the variable name if you wish, as in `bar' above.
Macro Definition
The directives .MACRO and .ENDM allow you to define your own
macros that generate assembly output.
.MACRO NAME
.MACRO NAME [ARG[=VALUE]...]
Begin the definition of a macro called NAME. If your macro
definition requires arguments, specify their names after the macro
name, separated by commas or spaces. Default values for macros arguments
may be specified in the format ARG=VALUE.
When you call a macro, you can specify the argument
values either by position, or by keyword. For example, `SUM 9, 17' is
equivalent to `SUM TO=17, FROM=9'. Macro arguments are preprocessor
variables similar to the variables you define with
.ASSIGNA or .ASSIGNC;
in particular, you can use them in conditionals or loop control. The only
difference is the prefix you write to evaluate
the variable: for a macro argument, write `\ARG', but for a
preprocessor variable, write `\&VAR'.
NAME .MACRO
NAME .MACRO ( [ARG[=VALUE]...] )
An alternative form of introducing a macro definition: specify the
macro name in the label position, and any arguments
between parentheses after the name.
.ENDM
Mark the end of a macro definition.
.EXITM
Exit early from the current macro definition, or macro loop.
\@
gasp maintains a counter of how many macros it has
executed in this pseudo-variable; you can copy that number to your output with
`\@', but only within a macro definition.
LOCAL NAME[, NAME...]
Generate a string replacement for each of the NAME argument, and
replace any instances of NAME in each macro expansion. The
replacement string is unique in the assembly, and different for
each separate macro expansion. LOCAL allows you to write macros
that define symbols, without fear of conflict between separate
macro expansions.
This is only available if you specify --alternate.
Data
These directives allow you to specify working areas of memory.
The directives that initialize memory are:
.DATA EXPR[, EXPR...]
.DATA.B EXPR[, EXPR...]
.DATA.W EXPR[, EXPR...]
.DATA.L EXPR[, EXPR...]
Evaluate arithmetic EXPR expressions, and emit the corresponding
as directive (labelled with LAB). The unqualified .DATA
emits .long; .DATA.B emits .byte; .DATA.W emits
.short; and .DATA.L emits .long.
For example, `foo .DATA 1,2,3' emits `foo: .long 1,2,3'.
.DATAB REPEAT, EXPR
.DATAB.B REPEAT, EXPR
.DATAB.W REPEAT, EXPR
.DATAB.L REPEAT, EXPR
Emit REPEAT copies of the value of the expression EXPR
(using the as directive .fill), being REPEAT an absolute
expression with an absolute value. .DATAB.B repeats one-byte
values; .DATAB.W repeats two-byte values; and .DATAB.L repeats
four-byte values. .DATAB without a suffix repeats four-byte
values, just like .DATAB.L.
.SDATA STR...
String data. Emits a concatenation of bytes (no end of string marks are
added, unlike in .SDATAZ) of each STR argument given, and
optionally separated by commas.
.SDATAB REPEAT, STR...
Repeated string data. REPEAT specifies how many
copies of the concatenation of every STR argument are emitted.
.SDATAZ STR...
Zero-terminated string data. Like .SDATA, except that
a zero byte is written at the end of the string.
.SDATAC STR...
Count-prefixed string data. Like .SDATA, except that gasp
precedes the string with a leading one-byte count. For example,
`.SDATAC "HI"' generates `.byte 2,72,73'. Since the count field
is only one byte, you can only use .SDATAC for strings less than
256 bytes in length.
Use the
.RES, .SRES, .SRESC, and .SRESZ
directives to reserve memory and leave it uninitialized. gasp
resolves these directives to appropriate calls of the GNU as .space
directive.
.RES COUNT
.RES.B COUNT
.RES.W COUNT
.RES.L COUNT
Reserve room for COUNT uninitialized elements of data. The suffix
specifies the size of each element: .RES.B reserves COUNT bytes,
.RES.W
reserves COUNT pairs of bytes, and
.RES.L
reserves
COUNT quartets.
.RES
without a suffix is equivalent to
.RES.L
.SRES COUNT
.SRES.B COUNT
.SRES.W COUNT
.SRES.L COUNT
.SRES
is a synonym for
.RES.
.SRESC COUNT
.SRESC.B COUNT
.SRESC.W COUNT
.SRESC.L COUNT
Like .SRES, but reserves space for `COUNT+1' elements.
.SRESZ COUNT
.SRESZ.B COUNT
.SRESZ.W COUNT
.SRESZ.L COUNT
.SRESZ
is a synonym for
.SRESC.
Listings
These directives control as listing directives.
.PRINT LIST
.PRINT NOLIST
Print control. This directive emits the GNU as directive
.list or .nolist, according to its argument.
.FORM LIN=LN
.FORM COL=COLS
.FORM LIN=LN COL=COLS
Specify the page size for assembly listings: LN represents the
number of lines, and COLS the number of columns. You may specify
either page dimension independently, or both together. By default, 60 lines
and 132 columns are used. Any values you may have specified in previous
instances of .FORM do not carry over as defaults. Emits the
.psizef
GNU as directive.
.HEADING STRING
Specify STRING as the title of your assembly listings. Emits
`.title "STRING"'.
.PAGE
Force a new page in assembly listings. Emits .eject.
MISCELLANEOUS COMMANDS
.ALTERNATE
Use the alternate macro syntax henceforth in the assembly.
.ORG
This command is recognized, but not yet implemented. gasp
generates an error message for programs that use .ORG.
.RADIX S
gasp understands numbers in any of base 2, 8, 10 or 16. You can
encode the base explicitly in any numeric constant. If you write numbers
without an explicit indication of the base, the most recent .RADIX S
command determines how they are interpreted. S is a case-insensitive
letter:
.RADIX B
Base 2.
.RADIX Q
Base 8.
.RADIX D
Base 10. This is the original default radix.
.RADIX H
Base 16.
.EXPORT NAME
.GLOBAL NAME
Declare NAME global (emits .global NAME). The two directives
are synonymous.
.PROGRAM
No effect: silently ignored.
.END
Mark end of each preprocessor file. A warning is issued if the end of file
is reached without seeing this command.
.INCLUDE STR
Preprocess the file named by STR, as if its contents appeared
where the .INCLUDE directive does. gasp imposes a
maximum limit of 30 stacked include files, as a sanity check.
.ALIGN SIZE
Evaluate the absolute expression SIZE, and emit the assembly
instruction .align SIZE using the result.
GASP SYNTAX
Whitespace (blanks or tabs; not newline) is partially significant, in that
it delimits up to three fields in a line. The amount of whitespace does
not matter.
* First field, an optional "label", must be flush left in a line
(with no leading whitespace) if it appears at all, with an optional color
after the label name.
* Second field, which must appear after some whitespace,
contains a gasp or as directive.
* Further fields on a line are arguments to the directive,
separated by either commas or whitespace.
Special syntactic markers
gasp recognizes a few special markers: to delimit comments, to
continue a statement on the next line, to separate symbols from other
characters, and to copy text to the output literally (One other
special marker, `@f', works only within macro definitions)
The trailing part of any source line may be a comment. A
comment begins with the first unquoted comment character (`!' by
default), or an escaped or doubled comment character (`\!' or
`!!' by default), and extends to the end of a line. The two kinds of
comment markers lead to slightly different treatment:
!
A single, un-escaped comment character generates an assembly
comment in the gasp output. gasp evaluates any preprocessor
variables (macro arguments, or variables defined with
.ASSIGNA or .ASSIGNC)
present. For example, a macro that begins like this
.MACRO SUM FROM=0, TO=9
! \FROM \TO
issues as the first line of output a comment that records the values you
used to call the macro.
\!
!!
Either an escaped comment character, or a double comment character,
marks a gasp source comment. fasp does not copy such comments to
the assembly output.
To continue a statement on the next line of the file, begin the
second line with the character `+'.
Occasionally you may want to prevent gasp from preprocessing some
particular bit of text. To copy literally from the gasp source to
its output, place `\(' before the string to copy, and `)' at the end.
For example, write `\(\!)' if you need the characters `\!' in your
assembly output.
To separate a preprocessor variable from text to appear
immediately after its value, write a single quote ('''). For example,
`.SDATA "P'1"' writes a string built by concatenating the value of `P'
and the digit `1' (You cannot achieve this by writing just `\P1',
since `P1' is itself a valid name for a preprocessor variable)
String and numeric constants
There are two ways of writing string constants: as literal
text, and by numeric byte value. Specify a string literal between
double quotes ("STR"). Specify an individual numeric byte value as
an absolute expression between angle brackets (<EXPR>). Directives
that output strings allow you to specify any number of either kind of
value, in whatever order is convenient, and concatenate the result.
You can write numeric constants either in a specific base, or in
whatever base is currently selected by the last .RADIX directive.
To write a number in a specific base, use the pattern `S'DDD': a
base specifier character S, followed by a single quote followed by
digits DDD. The base specifier character matches those you can specify
with .RADIX.
Symbols
gasp recognizes symbol and label names that start with any alphabetic
character, `_', or `$', and continue with any of the same
characters or with digits.
Arithmetic Expressions
There are two kinds of expressions, depending on their result:
absolute expressions, which resolve to a constant (that is, they do
not involve any values unknown to gasp), and relocatable expressions,
which must reduce to the form
ADDSYM+CONST-SUBSYM
where ADDSYM and SUBSYM are assembly symbols of unknown value, and
CONST is a constant.
Arithmetic for gasp expressions follows very similar rules to C.
You can use parentheses to change precedence; otherwise, arithmetic
primitives have decreasing precedence in the order of the following
list.
* 1. Single-argument `+' (identity), `-' (arithmetic opposite), or `~'
(bitwise negation). The argument must be an absolute expression.
* 2. `*' (multiplication) and `/' (division). Both
arguments must be absolute expressions.
* 3. `+' (addition) and `-' (subtraction). At least one argument must
be absolute.
* 4. `&' (bitwise and). Both arguments must be absolute.
* 5. `|' (bitwise or) and `~' (bitwise exclusive or; `^' in C).
Both arguments must be absolute.
String Primitives
You can use these primitives to manipulate strings (in the argument
field of gasp statements):
.LEN(STR)
Calculate the length of string "STR", as an absolute expression.
For example, `.RES.B .LEN("sample")' reserves six bytes of memory.
.INSTR(STR, SEG, IX)
Search for the first occurrence of SEG after position IX of
STR. The result is -1 if SEG does not occur in STR after
position IX.
.SUBSTR(STR, START, LEN)
The substring of STR beginning at byte number START and
extending for LEN bytes.
ALTERNATE MACRO SYNTAX
When the --alternate option is specified, an alternate macro sytax
is used by gasp. This syntax reminiscent of the syntax of Phar Lap
macro assembler, but it is not meant to be a full emulation of Phar Lap or
similar assemblers. In particular, GASP does not support directives such as
DB and IRP.
* You can use GASP preprocessor directives without a leading `.'
dot. For example, you can write `SDATA' with the same effect as .SDATA'.
* One additional directive, LOCAL, is available.
* You can write strings delimited like "STRING", 'STRING', or <STRING>
* To include any single character literally in a string (even if the
character would otherwise have some special meaning), you can
prefix the character with `!'. For example, `"hello !"world!"".
* You can write %EXPR to evaluate the expression
EXPR and use the result as a string.