view docs/ccguide/asm.appendix @ 653:06e11c941478

Completely finished
author roug
date Wed, 18 Dec 2002 09:14:14 +0000
parents ac4142f99b21
children
line wrap: on
line source

<appendix>
<title>Relocating Macro Assembler Reference</title>
<para>
This appendix gives a summary of the operation of the "Relocating
Macro Assembler" (named c.asm as distributed with the C Compiler).
This appendix and the example assembly source files supplied with
the C compiler should provide the basic information on how to use the
"Relocating Macro Assembler" to create relocatable-object format
files (ROF). It is further assumed that you are familiar with the
6809 instruction set and mnemonics. See the Microware Relocating
Assembler Manual for a more detailed description. The main function
of this appendix is to enable the reader to understand the output
produced by c.asm. The Relocating Macro Assembler allows programs
to be compiled separately and then linked together, and it also
allows macros to be defined within programs.
</para>
<para>
Differences between the Relocating Macro Assembler (RMA) and the
Microware Interactive Assembler (MIA):
</para>
<blockquote>
<para>
RMA does not have an interactive mode. Only a disk file is
allowed as input.
</para>
<para>
RMA output is an ROF file. The ROF file must be processed by
the linker to produce an executable OS9 memory module. The
layout of the ROF file is described later.
</para>
<para>
RMA has a number of new directives to control the placement of
code and data in the executable module. Since RMA does not
produce memory modules, the MIA directives "mod" and "emod" are
not present. Instead, new directives PSECT and VSECT control
the allocation of code and data areas by the linker.
</para>
<para>
RMA has no equivalent to the MIA "setdp" directive. Data (and
DP) allocation is handled by the linker.
</para>
</blockquote>
<section>
<title>Symbolic Names</title>
<para>
A symbolic name is valid if it consists of from one to nine
uppercase or lowercase characters, decimal digits or the characters
"$", "_", "." or "@". RMA does not fold lowercase letters to
uppercase. The names "Hi.you" and "HI.YOU" are distinct names.
</para>
</section>

<section>
<title>Label field</title>
<para>
If a symbolic name in the label field of a source statement is
followed by a <quote>:</quote> (colon), the name will be known
<emphasis>globally</emphasis> (by all modules linked together).
If no colon appears, the name will be known only in the PSECT
in which it was defined. PSECT will be described later.
</para>
</section>

<section>
<title>Undefined names</title>
<para>
If a symbolic name is used in an expression and hasn't been defined,
RMA assumes the name is external to the PSECT. RMA will record
information about the reference so the linker can adjust the operand
accordingly. External names cannot appear in operand expressions
for assembler directives.
</para>
</section>

<section>
<title>Listing format</title>
<programlisting>
00098 0032 59        +         rolb
00117 0045=17ffb8      label   lbsr  _dmove     Comment
^     ^   ^^         ^ ^       ^     ^          ^
|     |   ||         | |       |     |          Start of comment
|     |   ||         | |       |     Start of operand
|     |   ||         | |       Start of mnemonic
|     |   ||         | Start of label
|     |   ||         A "+" indicates a line generated by a macro
|     |   ||         expansion.
|     |   |Start of object code bytes.
|     |   An "=" here indicates that the operand contains an
|     |   external reference.
|     Location counter value
Line number.
</programlisting>
</section>

<section>
<title>Section Location Counters</title>
<para>
Each section contains the following location counters:
</para>
<variablelist termlength="5">
<varlistentry><term>PSECT</term>
<listitem><literallayout>instruction location counter</literallayout>
</listitem>
</varlistentry>
<varlistentry><term>VSECT</term>
<listitem><literallayout>initialized direct page location counter
non-initialized direct page location counter
initialized data location counter
non-initialized data location counter</literallayout>
</listitem>
</varlistentry>
<varlistentry><term>CSECT</term>
<listitem><literallayout>base offset counter</literallayout>
</listitem>
</varlistentry>
</variablelist>
</section>

<section>
<title>Section Directives</title>
<para>
RMA contains 3 section directives. PSECT indicates to the linker
the beginning of a relocatable-object-format file (<acronym>ROF</acronym>) and
initializes the instruction and data location counters and assembles
code into the <acronym>ROF</acronym> object code area. VSECT causes RMA to change to
the data location counters and place any generated code into the
appropiate <acronym>ROF</acronym> data area. CSECT initializes a base value for
assigning offsets to symbols. The end of these sections is indicated by the
ENDSECT directive.
</para>
<para>
The source statements placed in a particular section cause the
linker to perform a function appropiate for the statement.
Therefore, the mnemonics allowed within a section are restricted as
follows:
</para>
<itemizedlist>
<listitem>
<para>
The mnemonics are allowed inside or outside any section: nam,
opt, ttl, pag, spc, use, fail, rept, endr, ifeq, ifne, iflt,
ifle, ifge, ifgt, ifpl, endc, else, equ, set, macro, endm,
csect, and endsect.
</para>
</listitem>
<listitem>
<para>
Within a CSECT: rmb
</para>
</listitem>
<listitem>
<para>
Within a PSECT: any 6809 instruction mnemonic, fcc, fdb,fcs,
fcb, rzb, vsect, endsect, os9 and end.
</para>
</listitem>
<listitem>
<para>
Within a VSECT: rmb, fcc, fdb, fcs, fcb, rzb and endsect.
</para>
</listitem>
</itemizedlist>
<section>
<title>PSECT Directive</title>
<para>
The main difference between PSECT and MOD is that MOD sets up
information for OS-9 and PSECT sets up information for the
linker (c.link in the C compiler).
</para>
<informalexample>
<para>
PSECT {name,typelang,attrrev,edition,stacksize,entrypoint}
</para>
<informaltable frame="none">
<tgroup cols="2">
<colspec colwidth="0.8in"/>
<colspec colwidth="3.2in"/>
<tbody>
<row>
<entry>name</entry>
<entry>Up to 20 bytes (any printable character except space
or comma) for a name to be used by the linker to
identify this PSECT. This name need not be distinct
from all other PSECTs linked together, but it helps
to identify PSECTs the linker has a problem with if
the names are different.</entry>
</row> 
<row>
<entry>typelang</entry>
<entry>byte expression for the executable module type/language
byte. If this PSECT is not a "mainline"
(a module that has been designed to be forked to) module
this byte must be zero.</entry>
</row> 
<row>
<entry>attrrev</entry>
<entry>byte expression for executable module attribute/revision byte.</entry>
</row> 
<row>
<entry>edition</entry>
<entry>byte expression for executable module edition byte.</entry>
</row> 
<row>
<entry>stacksize</entry>
<entry>word expression estimating the amount of stack storage
required by this psect. The linker totals this
value in all PSECTs to appear in the executable module and
adds this value to any data storage requirement
for the entire program.</entry>
</row> 
<row>
<entry>entrypoint</entry>
<entry>word expression entrypoint offset for this PSECT.
If the PSECT is not a mainline odule, this should
be set to zero.</entry>
</row> 
</tbody>
</tgroup>
</informaltable>
</informalexample>
<para>
PSECT must have either no operand list or an operand list
containing a name and five expressions. If no operand list is
provided, the PSECT name defaults to "program" and all other
expressions to zero. The can only be one PSECT per assembly
language file.
</para>
<para>
The PSECT directive initializes all counter orgs and marks the
start of the program module. No VSECT data reservations or
object code may appear before or after the PSECT/ENDSECT block.
</para>
<para>
Example:
<programlisting>
psect myprog,Prgrm+Objct,Reent+1,Edit,0,progent
psect another_prog,0,0,0,0,0
</programlisting>
</para>
</section>

<section>
<title>VSECT Directive</title>
<para>
VSECT {DP}
</para>
<para>
The VSECT directive causes RMA to change to the data location
counters. If DP appears after VSECT, the direct page counters are
used, otherwise the non-direct page data is used. The RMB directive
within this section reserves the specified number of bytes in the
appropiate uninitialized data section. The fcc, fdb, fcs, fcb and
rzb (reserve zeroed bytes) directives place data into the
appropiate initialized data section. If an operand for fdb or fcb
contains an external reference, this information is placed in the
external reference part of the ROF to be adjusted at link or
execution time. ENDSECT marks the end of the VSECT block. Any
number of VSECT blocks can appear within a PSECT. Note, however,
that the data location counters maintain their values between one
VSECT block and the next. Since the linker handles the actual data
allocation, there is no facility provided to adjust the data
location counters.
</para>
</section>

<section>
<title>CSECT Directive</title>
<para>
CSECT {expression}
</para>
<para>
The CSECT directive provides a means for assigning consecutive
offsets to labels without resorting to EQUs. If the expression is
present, the CSECT base counter is set to that value, otherwise it
is set to zero.
</para>
</section>

<section>
<title>RZB statement</title>
<para>
RZB &lt;expression&gt;
</para>
<para>
The reserve zeroed bytes pseudo-instruction generates sequences of
zero bytes in the code or initialized data sections, the number of
which is specified by the expression.
</para>
</section>
</section>

<section>
<title>Comparison Between Assembly Programs for the Microware Interactive Assember
and the Relocating Macro Assembler</title>
<para>
The following two program examples simply fork a BASIC09. The
purpose of the examples are to show some of the differences in the
new relocating assembler. The differences are apparent.
</para>
<programlisting>
* this program forks a basic09
          ifp1
          use ..../defs/os9defs.a
          endc

PRGRM     equ $10
OBJCT     equ $01

stk       equ 200
          psect rmatest,$11,$81,0,stk,entry
          
name      fcs /basic09/
prm       fcb $D
prmsize   equ *-prm

entry     leax name,pcr
          leau prm,pcr
          ldy #prmsize
          lda #PRGRM+OBJCT
          clrb
          os9 F$FORK
          os9 F$WAIT
          os9 F$EXIT
          endsect
</programlisting>
<section>
<title>Macro Interactive Assembler Source</title>
<programlisting>
          ifp1
          use defsfile
          endc

          mod siz,prnam,type,revs,start,size
prnam     fcs /testshell/
type      set prgm+objct
revs      set reent+1

          rmb 250
          rmb 200
name      fcs /basic09/
prm       fcb $D
prmsize   equ *-prm
size      equ .
start     equ *
          leax name,pcr
          leau prm,pcr
          ldy #prmsize
          lda #PRGRM+OBJCT
          clrb
          os9 F$FORK
          os9 F$WAIT
          os9 F$EXIT
          emod
siz       equ
</programlisting>
</section>
</section>

<section>
<title>Introduction to Macros</title>
<para>
In programming applications it is frequently necessary to use a
repeated sequence or pattern of instructions in many different
places in a program. For example, suppose a group of program
statements creates a file a number of times throughout the program.
The code might look like the following statements:
</para>
<screen>
    leax name,pcr
    lda $02
    ldb $03
    os9 I$CREATE
</screen>
<para>
The sequence must be replicated each time that a new file is
created. A macro assembler eliminates the need for coding duplicate
statement patterns by allowing the programmer to define macro
instructions that are equivalent to longer code sequences.
</para>
<para>
When a macro is called, it is the same as calling a subrouting to
perform a defined function. A macro produces in-line code that is
inserted into the normal flow of the program beginning at the
location of the macro call. The statements that may be generated by
a macro are generally unrestricted, and the statements may contain
substitutable arguments.
</para>
</section>

<section>
<title>Operations</title>

<section>
<title>Macro Definition</title>
<para>
A macro definition consists of three sections:
</para>
<screen>
      &lt;Label&gt; MACRO    /* macro header */
              .        /* &lt;Label&gt; is the name of the macro */
              .
              body     /* macro body */
              .
              .
              ENDM     /* macro terminator */
</screen>
<orderedlist numeration="arabic" spacing="compact">
<listitem>
<para>The macro header - assigns a name to the macro</para>
</listitem>
<listitem>
<para>The body - contains the macro statements</para>
</listitem>
<listitem>
<para>The terminator - indicates the end of the macro</para>
</listitem>
</orderedlist>
<para>
A macro can have up to nine arguments (\1 to \9) in the operand
fields. The arguments are used to refer to symbols, registers, etc.
</para>
<para>
The following macro below could represent the file creation pattern:
</para>
<programlisting>
CREATE MACRO
       leax \1,pcr
       lda $\2
       ldb $\3
       os9 I$CREATE
       ENDM
</programlisting>
<para>
Calls can be made to create files with different names, access
modes, and attributes as follows:
</para>
<programlisting>
CREATE name2,02,03
CREATE name3,01,02
</programlisting>
<para>
The above macro calls will produce the following in-line code:
</para>
<programlisting>
       leax name2, pcr
       lda $02
       ldb $03
       os9 I$CREATE

       leax name3, pcr
       lda $01
       ldb $02
       os9 I$CREATE
</programlisting>
<para>
If an argument has multiple parts, for example if d1,d2 is to be
passed to the macro called frud, it must be passed in double quotes.
For example:
</para>
<programlisting>
frud "0,s","2,s"
</programlisting>
<para>
If frud looks like the following macro:
<programlisting>
frud MACRO
\@   leau \1
     ldd  \2
     beq  \@
     ENDM
</programlisting>
The previous call to frud would expand the macro as follows:
<programlisting>
@xxx  leau 0,s
      ldd  2,s
      beq  @xxx
</programlisting>
Where "\@" is a label, and "xxx" would be replaced
by a three digit number.
</para>
<para>
An argument may be declared null by leaving it blank in the macro
call. For example, if the macro instruction was "ldd \1ZZ\2", then
the call to the macro with arguments AA,BB would expand the
instruction to "ldd AAZZBB", and the call with argument ,BB will
expand it to "ldd ZZBB".
</para>
</section>

<section>
<title>Nested Macro Calls</title>
<para>
Macro calls may be nested, that is, the body of a macro definition
may contain a call to another macro. For example, the macro prepw
could be defined as follows:
<programlisting>
prepw MACRO
      lda \1
      getw
      ENDM
</programlisting>
Getw is a macro call. The code to getw is substituted in-line at
expansion time. However, the definition of a new macro within
another is not permitted. Macro calls may be nested up to eight deep.
</para>
</section>

<section>
<title>Labels</title>
<para>
Sometimes it is necessary to use labels within a macro. Labels are
specified by <quote>\@</quote>. Each time the macro is called, a unique label
will be generated to avoid multiple definition errors. Within the
expanded code <quote>\@</quote> will take on the form <quote>@xxx</quote>, where xxx
will be a decimal number between 000 to 999.
</para>
<para>
More than one label may be specified in a macro by the addition of
an extra character(s). For example, if two different labels are
required in a macro, they can be specified by "\@A" and "\@B". In
the first expansion of te macro, the labels would be "@001A" and
"@001B", and in the second expansion they would be "@002A" and
"@002B". The extra characters may be appended before the "\" or
after the "@".
</para>
</section>

<section>
<title>Additional Pseudo-Instructions</title>
<variablelist>
<varlistentry><term>\n</term>
<listitem>
<para>
will return the number of arguments passed to the macro.
</para>
</listitem>
</varlistentry>

<varlistentry><term>\L&lt;num&gt;</term>
<listitem>
<para>
will return the length of the ith argument
that is specified by &lt;num&gt;.
</para>
</listitem>
</varlistentry>

<varlistentry><term>FAIL</term>
<listitem>
<para>
Causes an error to be generated.
</para>
</listitem>
</varlistentry>

<varlistentry><term>REPT &lt;num&gt;</term>
<listitem>
<para>
will repeat an instruction or group of instructions &lt;num&gt; times.
ENDR terminates REPT.
</para>
</listitem>
</varlistentry>

</variablelist>
</section>
</section>
</appendix>