home *** CD-ROM | disk | FTP | other *** search
- APP - Assembly Pre-Processor
- ----------------------------
-
- Version 2.0, 28-April-1990
-
- PUBLIC DOMAIN
-
- written by Karl Lehenbauer, first release 12/8/88, with a lot of design
- input by Peter da Silva.
-
- Version 2.0, released 4/28/90, incorporated changes by Brett Bourbin
- (Selgus Limited) involving input/output file handling and added the dbra
- looping construct. Karl made a backwards-compatible version of the new
- i/o file handling, converted to ANSI C, spruced up the docs, etc.
-
-
- Disclaimer and Redistribution Information
- -----------------------------------------
-
- APP is placed freely into the public domain for any use without restriction.
- APP comes without warranties, expressed or implied. This is free software.
- We don't have a contract.
-
- We're not asking for money for this, but if you use it a lot, a check for
- $10 or $20 would always be appreciated. Make checks to Hackercorp, 3918
- Panorama, Missouri City, TX 77459
-
-
- What it is
- ----------
-
- APP is a preprocessor for the 68000 assembler that comes with Aztec C for
- the Amiga. It will probably work with other 68000 assemblers. It works
- fine with 68020/68030 instructions, too. It can easily be adapted to
- other processor architectures as well.
-
- APP provides structured programming constructs for the assembly language
- programmer. Specifically, APP provides support for IF-THEN-ELSE-ELSEIF-
- ENDIF constructs and for DO-WHILE-UNTIL-ENDDO constructs.
-
- Consider the C pseudocode fragment:
-
- long a, b;
-
- if (a < 0)
- {
- less_than_zero_stuff();
- }
- else
- {
- not_less_that_zero_stuff();
- }
-
- In assembler (or pre-77 FORTRAN, for example) to do the same thing requires
- the creation of two bogus labels, as in:
-
- move.l _a,d0
- bge else_part
- jsr _less_than_zero_stuff
- bra past_the_else
- else_part
- jsr _not_less_than_zero_stuff
- past_the_else
-
- When you start nesting these deeply, the code quickly becomes unreadable.
- Note also that you have to reverse the sense to branch around the code
- you really want to execute. This makes the code less clear.
- If the assembler had structured programming constructs like C, Modula 2,
- Forth, etc, the creation of these superfluous labels is unnecessary.
- Using APP, the above code fragment can be rewritten:
-
- move.l _a,d0
- .if lt
- jsr _less_than_zero_stuff
- .else
- jsr _not_less_than_zero_stuff
- .endif
-
- To define an "if", enter an opcode of ".if" and an operand of a condition
- code that the assembler recognizes as a branch when following behind a 'b',
- as in condition codes "le", "lt", "eq", "ne", "gt", "ge" yielding "ble",
- "blt", "beq", "bne", "bgt", "bge" You will have issued instructions to
- set up the condition codes before the ".if".
-
- For "if", APP will assemble a conditional branch with the sense reversed,
- branching to the matching ".else", ".elseif", or ".endif". APP will make
- up labels and produce the equivalent branching code as above. I have chosen
- to make APP's labels be 'L' followed by an increasing sequential integer
- label number. This was chosen to avoid conflicting with Manx's '.' followed
- by the number so you can incrementally "structurize" and test as you hand
- optimize the output of cc with optimization and assembly source generation
- flags selected.
-
- APP also supports a do/enddo construct. The way it works is ".enddo"
- compiles a "branch always" instruction back to the corresponding ".do".
- To exit the do/enddo, three constructs are provided. These are ".while",
- ".until" and ".dbra". ".while" takes a condition code and, if it is true,
- execution continues below the while, else a branch past the enddo is
- taken. ".until" in the opposite manner, if the condition code is true
- a branch past the enddo is taken otherwise it isn't. (".dbra" will be
- described later below.) For example,
-
- .do
- ;conditional setup stuff
- .
- .
- .while ne
- ; execution stuff
- .
- .
- .enddo
-
- ...will execute code between the do and the enddo until the condition code
- at the "while" isn't true anymore. Multiple .whiles and .untils may be
- used and .whiles and .untils may be freely intermixed.
-
- An additional do structure provided on the 68000 series to take advantage
- of specific 68000 looping capabilities. This is the decrement-and-branch,
- DBRA, instruction. Using DBRA, many simple copying loops can be coded with
- only two instructions. Consequently, dbra is provided as a .do-terminating
- instruction as an alternative to .enddo, as in:
-
- .do
- ; loop code
- ;
- .dbra d5
-
- In the preceding example, the loop code will be executed a number of times
- equal to the value in d5, with the dbra instruction decrementing d5 each
- time through the loop until d5 is zero when dbra checks it, at which time
- it will "fall through", executing the next instruction after the dbra.
-
- Note that .dbra is different from dbra in that .dbra indicates to app
- that it terminates a matching .do, thus that app is to generate a dbra
- instruction to decrement the specified register and branch back to the
- corresponding .do statement, while a "dbra" is just a regular dbra
- instruction, app just passes it through, and it requires the register and
- a label like any other label-branching instruction on the 68000.
-
-
- Nesting of conditionals is permitted to a depth of 32. When nesting, I
- reccommend indenting your code, as in:
-
- tst.l d0
- .if gt
- add.l d0,d1
- cmp.l #max,d1
- .if gt
- move.l #max,d1
- .endif
- .endif
-
- Setting tab stops at four seems to work well.
-
-
- How To Invoke APP
- -----------------
-
- APP takes the name of the structured assembly source it is to compile
- into standard assembly source code on the command line, as in
-
- app foo.app
-
- This produces foo.asm, if app doesn't detect any errors while processing
- the file.
-
- When used in the above manner, the name of the source file must end with
- .app, and app will always create the output file with a .asm extension.
-
- Alternatively, you may specify the output file, as in:
-
- app -o foo.asm foo.a
-
- Note that for the second form, the .app extension of the source filename
- is not required.
-
-
- Integrating APP with your makefile
- ----------------------------------
-
- If you add the following rules to your makefile and list object files
- corresponding to your assembly preprocessor source .app files in your
- make dependencies, make will run APP over your .app files and then
- run "as" over the resulting .asm files automatically.
-
- .app.o:
- app $*.app
- as $*.asm
-
-
- Condition Codes Known by APP
- ----------------------------
-
- The following condition codes may be used APP's .if, .elseif, .while
- and .until statements:
-
- "ne"
- "eq"
- "lt"
- "ge"
- "le"
- "gt"
- "cc"
- "cs"
- "vc"
- "vs"
- "hi"
- "ls"
- "pl"
- "mi"
-
- Consult your 68000 Reference Manual if you need to know
- what status register bits and states correspond to these
- codes. They're the standard ones.
-
-
- APP Error Messages
- ------------------
-
- APP does a lot of checking of your APP "dot" statements to insure their
- validity. Specifically, APP insures that all .ifs have matching .endifs,
- that all .dos have matching .enddo or .dbra, that only one .else is
- specified inside a .if, that .elseifs are only specified inside .ifs,
- that .whiles and .untils are only specified inside a .do and that all
- "dot" structures are closed at end of file. If APP does detect an error,
- it prints an error message including the line number and exits. (It could
- conceivably go on, but I have yet to take it this far.)
-
- If APP is pointing to the last line in the file, the problem is that you
- didn't close a .if or .do structure somewhere earlier in the file.
-
- If APP exits with an error, it removes the .asm output file so the file
- won't confuse "make" into thinking everything went OK with APP when it
- really didn't.
-
-
- Enumeration of Variations by Pseudo-Example
- -------------------------------------------
-
- .if cc
- .endif
-
- .if cc
- .else
- .endif
-
- .if cc
- .elseif cc
- .endif
-
- .if cc
- .elseif cc
- .elseif cc
- .endif
-
- .do
- .enddo
-
- .do
- .while cc
- .enddo
-
- .do
- .until cc
- .enddo
-
- .do
- .until cc
- .until cc
- .while cc
- .enddo
-
- .do
- .dbra reg
-
- .do
- .until cc
- .while cc
- .dbra reg
-
-
- Miscellaneous Notes
- -------------------
-
- APP conditionals may be nested up to 32 levels deep. If you need to go
- deeper (seven or eight seems like the realistic-use upper limit to me),
- change the MAX_NESTING_LEVELS define in app.c.
-
- All the APP constructs must be entered in lower case only, and the condition
- codes as well.
-
- Note that the functions provided by APP could have been done by assembler
- macros if the Aztec assembler had supported the ability to expand a macro
- with an argument being the *value* of a SET variable, had string variables
- or the ability to concatenate text with a SET variable -- it doesn't, and
- similar problems appear in other assemblers as well.
-
- Note also that APP doesn't check condition codes for validity unless their
- sense has to be reversed. It probably should check them, but invalid ones
- won't get past the assembler in any case.
-
- APP is so vanilla in its construction that it should run on about any
- machine with a C compiler and a stdio library. It for sure runs under
- Aztec C on the Amiga and on Intel '286 Multibus Xenix (don't ask why).
- Version 1.1 and onward, though, require an ANSI standard C compiler.
-
- The documentation was significantly more work than the code.
-
- Warm Regards,
- Karl @ The Alternate Hacker's Haven -- Houston, TX, 12/11/88
- updated - 4/28/90
- Usenet: uunet!sugar!karl Internet/BITNET: karl@sugar.hackercorp.com
-
-