home *** CD-ROM | disk | FTP | other *** search
- ---COMPAT.DOC---
-
- Compatibility with "standard" assembly language
-
- I gave heavy priority to compatibility when I designed A86; a priority just a
- shade behind the higher priorities of reliability, speed, convenience, and
- power. For those of you who feel that "close, but incompatible" is like saying
- "a little bit pregnant", I'm sorry to report that A86 will not assemble all
- Intel/IBM/MSDOS programs, unmodified. But I do think that a vast majority of
- programs ultimately producing .COM files can, with a surprisingly little amount
- of massaging, be made to assemble under A86. Furthermore, the massaging can be
- done in such a way as to make the programs still acceptible to that old,
- behemoth assembler.
-
-
- Conversion of Intel/IBM/MSDOS programs to A86
-
- Following is a list of the things you should watch out for when converting from
- Intel/IBM to A86:
-
- 1. If your program does not fit into 64K, with all the segment registers
- pointing to the same value, then there may be instructions in the program
- for which the old assembler generates segment-override prefixes "behind your
- back". You will need to find such references, and generate explicit
- overrides for them. If there are data-tables within the program itself, a
- CS-override is needed. If there are data-structures in the stack segment
- not accessed via a BP-index, an SS-override is needed. If ES points to its
- own segment, then an ES-override is needed for accesses (other than STOS and
- MOVS destinations) to that segment.
-
- If you want to remain compatible with the old assembler, then you code the
- overrides by placing the segment register name, with a colon, before the
- memory-access operand in the instruction. If you do not need further
- compatibility, you can place the segment register name before the
- instruction mnemonic. For example:
- MOV AL,CS:TABLE[SI] ; if you want compatibility do it this way
- CS MOV AL,TABLE[SI] ; if not you can do it this way
-
- 2. A86 is a bit more restrictive with respect to forward-references than IBM's
- assembler. In particular, forward references to variable-names are not
- allowed. What this means is that you must move variable-declarations to the
- top of your program (a sound practice anyway). Sometimes this means that
- you must add a JMP statement the very top of the program, around the
- variable declarations, to the start of execution-code.
-
- 3. A86 has the feature, not seen in Intel/IBM, that the default base for
- numbers with leading digit 0 is hexadecimal, not decimal. This means that
- you must remove any leading zeroes from decimal numbers in your old
- programs. Note that all constants other than those without leading zeroes
- and without trailing base-specifiers are handled identically by A86 and by
- Intel/IBM. The ONLY thing you need to worry about is decimal numbers with
- leading zeroes. Example: the old code line MOV AX,00100, meaning decimal
- 100, should be recoded MOV AX,100, without the leading zeroes.
-
- Alternatively, I have added the RADIX command, for compatibility with the
- .RADIX command of IBM's assembler. If the program has a .RADIX command at
- the top of it, then my assembler will handle constants identically to the
- IBM assembler; if it does not, you can add a .RADIX 10 to the top of the
- program, for complete compatiblity.
-
- 4. A86's macro definition language is different than Intel/IBM's. Most macros
- can be translated by replacing the named parameters of the old macros with
- the dedicated names #n of the A86 macro language; and by replacing ENDM
- with #EM. To retain compatibility, you isolate the old macro definitions
- in an INCLUDE file (A86 will ignore the INCLUDE directive), and isolate the
- A86 macro definitions in a separate file, not used in an Intel/IBM assembly
- of the program.
-
- 5. A86 supports a simpler segmentation model than Intel/IBM's. The program
- should go into a segment called CODE. Data is declared in a single segment
- called DATA. To convert an old program to A86, you must fit all the segments
- of the old program into the simpler model. If the old program produces a
- .COM file, this shouldn't be hard: the segmentation model must already be
- simple, to accomodate the .COM format.
-
- As an additional compatiblity feature, I assume that all named segments with
- names other than DATA are code segments; and I implicity EQU the name to
- CODE. For example, a CSEG SEGMENT directive with be treated just as a
- CODE SEGMENT directive.
-
- 6. A86 does not support a couple of the more exotic features of Intel/IBM
- assembly language: the RECORD directive and its associated operators
- WIDTH and MASK; and the usage of angle-brackets to initialize structure-
- records. These features would have added much complication to the
- internal structure of symbol tables in A86; degrading the speed and the
- reliability of the assembler. I felt that their use was sufficiently rare
- that it was not worth including them for compatibility. I would like to
- hear some feedback on this. Does anybody out there use these features
- heavily? Will they be missed in A86?
-
- If your old program does use these features, you will have to re-work the
- areas that use them. Macros can be used to duplicate the record and
- structure initializations. Explicit symbol declarations can replace the
- usage of the WIDTH and MASK operators.
-
-
- Compatiability-symbols recognized by A86
-
- A86 has been programmed to ignore a variety of lines that have meaning to
- Intel/IBM/MSODS assemblers; but which do nothing for A86. These include lines
- beginning with a period (execpt .RADIX, which is acted upon), percent sign, or
- dollar sign; and lines beginning with ASSUME, END, EXTRN, INCLUDE, NAME, PAGE,
- PUBLIC, SUBTTL, and TITLE. If you are porting your program to A86, and you wish
- to retain the option of returning to the other assembler, you may leave those
- lines in your program. If you decide to stay with A86, you can remove those
- lines at your leisure.
-
-
- Conversion of A86 Programs to Intel/IBM/MSDOS
-
- I consider this section a bit of a blasphemy, since it's a little silly to
- port programs from a superior assembler, to run on an inferior one.
- However, I myself have been motivated to do so upon occasion. Possible
- reasons include:
-
- * Programming for a client not familiar with A86; or whose computer doesn't
- run A86; who therefore wants the final version to assemble on Intel's
- assembler. Since my assembler/debugger environment is so vastly superior
- to any other environment, I develop the program using my assembler, and
- port it to the client's environment at the end.
-
- * Programming a module to link to a high-level language. Again, I debug
- the module in my superior environment; then port it.
-
- The main key to success in following the above scenarios is to exercise supreme
- will power, and not use any of the wonderful language features that exist on
- A86, but not on the Intel/IBM assembler. This is often not easy; and I have
- devised some methods for porting my features to Intel/IBM assemblers:
-
- 1. I hate giving long sequences of PUSHes and POPs on separate lines. If the
- program is to be ported to a lesser assembler, then I put the following lines
- into a file that only A86 will see:
- PUSH2 EQU PUSH
- PUSH3 EQU PUSH
- POP2 EQU POP
- POP3 EQU POP
-
- I define macros PUSH2, PUSH3, POP2, POP3 for the lesser assembler, that PUSH
- or POP the appropriate number of operands. Then, everywhere in the program
- where I would ordinarily use A86's multiple PUSH/POP feature, I use one or
- more of the PUSHn/POPn mnemonics instead.
-
- 2. I refrain from using the feature of A86 whereby constants with a leading zero
- are default-hexadecimal. All my hex constants end with H.
-
- 3. I will usually go ahead and use my local labels L0 through L9; then at the
- last minute convert them to a long sequence of labels in sequence: Z100,
- Z101, Z102, etc. I take care to remove all the ">" forward-reference
- specifiers when I make the conversion. The "Z" is used to isolate the local
- labels at the end of the lesser assembler's symbol-table listing. This
- improves the quality of the final program so much that it is worth the extra
- effort needed to convert L0--L9's to Z100-Zxxx's.
-
- 4. I will place declarations B EQU DS:BYTE PTR 0 and W EQU DS:WORD PTR 0 at the
- top of the program. Recall that A86 has a "duplicate definition" feature
- whereby you can EQU an already-existing symbol, as long as it is equated to
- the value it already has. This feature extends to the built in symbols B
- and W, so A86 will look at those equates and essentially ignore them. On
- the old assembler, the effect of the declarations is to add A86's notation
- to the old language. Example:
-
- B EQU DS:BYTE PTR 0
- W EQU DS:WORD PTR 0
- MOV AX,W[0100] ; replaces MOV AX, DS:WORD PTR 0100
- MOV AL,B[BX] ; replaces MOV AL, DS:BYTE PTR [BX]
-
- Note that I've just given you a tip that means even if you don't choose to
- use A86, you'll never have to use BYTE PTR or WORD PTR again! Now don't you
- just hate BYTE PTR and WORD PTR? Isn't the tip alone worth sending me at
- least $5 for?
-