Mercurial > hg > Members > kono > nitros9-code
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 <expression> </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> <Label> MACRO /* macro header */ . /* <Label> 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<num></term> <listitem> <para> will return the length of the ith argument that is specified by <num>. </para> </listitem> </varlistentry> <varlistentry><term>FAIL</term> <listitem> <para> Causes an error to be generated. </para> </listitem> </varlistentry> <varlistentry><term>REPT <num></term> <listitem> <para> will repeat an instruction or group of instructions <num> times. ENDR terminates REPT. </para> </listitem> </varlistentry> </variablelist> </section> </section> </appendix>