home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / A86V322.ZIP / A12.DOC < prev    next >
Text File  |  1990-01-25  |  13KB  |  285 lines

  1. CHAPTER 12   COMPATIBILITY WITH OTHER ASSEMBLERS
  2.  
  3.  
  4. I gave heavy priority to compatibility when I designed A86; a
  5. priority just a shade behind the higher priorities of
  6. reliability, speed, convenience, and power.  For those of you who
  7. feel that "close, but incompatible" is like saying "a little bit
  8. pregnant", I'm sorry to report that A86 will not assemble all
  9. Intel/IBM/MASM programs, unmodified.  But I do think that a vast
  10. majority of programs can, with a little massaging, be made to
  11. assemble under A86.  Furthermore, the massaging can be done in
  12. such a way as to make the programs still acceptable to that old,
  13. behemoth assembler.
  14.  
  15. Version 3.00 of A86 has many compatibility features not present
  16. in earlier versions.  Among the features added since A86 was
  17. first released are:  more general forward references, double
  18. quotes for strings, "=" as a synonym for EQU, the RADIX
  19. directive, and the COMMENT directive.  If you tried feeding an
  20. old source file to a previous A86 and were dismayed by the number
  21. of error messages you got, try again: things might be more
  22. manageable now.
  23.  
  24.  
  25. Conversion of MASM programs to A86
  26.  
  27. Following is a list of the things you should watch out for when
  28. converting from MASM to A86:
  29.  
  30. 1. You need to determine whether the program was coded as a COM
  31.    program or as an EXE program.  All COM programs coded for MASM
  32.    will contain an ORG 100H directive somewhere before the start
  33.    of the code.  EXE programs will contain no such ORG, and will
  34.    often contain statements that load named segments into
  35.    registers.  If the program was coded as EXE, you must either
  36.    assemble it (using the +O option) to an OBJ file to be fed to
  37.    LINK, or you must eliminate the instructions that load segment
  38.    registers-- in a COM program they often aren't necessary
  39.    anyway, since COM programs are started with all segment
  40.    registers already pointing to the same value.
  41.  
  42.    A good general rule is: when it doubt, try assembling to an
  43.    OBJ file.
  44.  
  45. 2. You need to determine whether the program is executing with
  46.    all segment registers pointing to the same value.  Simple COM
  47.    programs that fit into 64K will typically fall into this
  48.    category.  Most EXE programs, programs that use huge amounts
  49.    of memory, and programs (such as memory-resident programs)
  50.    that take over interrupts typically have different values in
  51.    segment registers.
  52.                                                              12-2
  53.  
  54.    If there are different values in the segment registers, then
  55.    there may be instructions in the program for which the old
  56.    assembler generates segment override prefixes "behind your
  57.    back".  You will need to find such references, and generate
  58.    explicit overrides for them.  If there are data tables within
  59.    the program itself, a CS-override is needed.    If there are
  60.    data structures in the stack segment not accessed via a
  61.    BP-index, an SS-override is needed. If ES points to its own
  62.    segment, then an ES-override is needed for accesses (other
  63.    than STOS and MOVS destinations) to that segment.  In the
  64.    interrupt handlers to memory-resident programs, the "normal"
  65.    handler is often invoked via an indirect CALL or JMP
  66.    instruction that fetches the doubleword address of the normal
  67.    handler from memory, where it was stored by the initialization
  68.    code.  That CALL or JMP often requires a CS-override-- watch
  69.    out!
  70.  
  71.    If you want to remain compatible with the old assembler, then
  72.    code the overrides by placing the segment register name, with
  73.    a colon, before the memory-access operand in the instruction.
  74.    If you do not need further compatibility, you can place the
  75.    segment register name before the instruction mnemonic.  For
  76.    example:
  77.  
  78.     MOV AL,CS:TABLE[SI]   ; if you want compatibility do this
  79.     CS MOV AL,TABLE[SI]   ; if not you can do it this way
  80.  
  81. 3. You should use a couple of A86's switches to maximize
  82.    compatibility with MASM.  I've already mentioned the +O switch
  83.    to produce .OBJ files.  You should also assemble with the +D
  84.    switch, which disables A86's unique parsing of constants with
  85.    leading zeroes as hexidecimal.  The RADIX command in your
  86.    program will also do this. And you should use the +L15 switch,
  87.    that disables a few other A86 features that might have reduced
  88.    compatibility. See Chapter 3 for a detailed explanation of
  89.    these switches.
  90.  
  91. 4. A86 is a bit more restrictive with respect to forward
  92.    references than MASM, but not as much as it used to be. You'll
  93.    probably need to resolve just a few ambiguous references by
  94.    appending " B" or " W" to the forward reference name.  One
  95.    common reference that needs a bit more recoding is the
  96.    difference of two forward references, often used to refer to
  97.    the size of a block of allocated memory.  You handle this by
  98.    defining a new symbol representing the size, using an EQU
  99.    right after the block is declared, and then replacing the
  100.    forward-reference difference with the size symbol.
  101.  
  102. 5. A86's macro definition and conditional assembly language is
  103.    different than MASM's.  Most macros can be translated by
  104.    replacing the named parameters of the old macros with the
  105.    dedicated names #n of the A86 macro language; and by replacing
  106.    ENDM with #EM.  Other constructs have straightforward
  107.    translations, as illustrated by the following examples.  Note
  108.    that examples involving macro parameters have double pound
  109.    signs, since the condition will be tested when the macro is
  110.    expanded, not when it is defined.
  111.                                                              12-3
  112.  
  113.    MASM construct              Equivalent A86 construct
  114.  
  115.    IFE expr                     #IF ! expr
  116.    IFB <PARM3>                  ##IF !#S3
  117.    IFNB <PARM4>                 ##IF #S4
  118.    IFIDN <PARM1>,<CX>           ##IF "#1" EQ "CX"
  119.    IFDIF <PARM2>,<SI>           ##IF "#2" NE "SI"
  120.    .ERR                         (any undefined symbol)
  121.    .ERRcond                     TRUE EQU 0FFFF
  122.                                 TRUE EQU cond
  123.    EXITM                        #EX
  124.    IRP ... ENDM                 #RX1L ... #ER
  125.    REPT 100 ...ENDM             #RX1(100) ... #ER
  126.    IRPC ... ENDM                #CX ... #EC
  127.  
  128.    The last three constructs, IRP, REPT, and IRPC, usually occur
  129.    within macros; but in MASM they don't have to.  The A86
  130.    equivalents are valid only within macros-- if they occur in
  131.    the MASM program outside of a macro, you duplicate them by
  132.    defining an enclosing macro on the spot, and calling that
  133.    macro once, right after it is defined.
  134.  
  135.    To retain compatibility, you isolate the old macro definitions
  136.    in an INCLUDE file (A86 will ignore the INCLUDE directive),
  137.    and isolate the A86 macro definitions in a separate file, not
  138.    used in an MASM assembly of the program.
  139.  
  140. 6. A86 supports the STRUC directive, with named structure
  141.    elements, just like MASM, with one exception: A86 does not
  142.    save initial values declared in the STRUC definition, and A86
  143.    does not allow assembly of instances of structure elements.
  144.  
  145.    For example, the MASM construct
  146.  
  147.    PAYREC STRUC
  148.       PNAME  DB 'no name given'
  149.       PKEY   DW ?
  150.    ENDS
  151.  
  152.    PAYREC 3 DUP (?)
  153.    PAYREC <'Eric',1811>
  154.  
  155.    causes A86 to accept the STRUC definition, and define the
  156.    structure elements PNAME and PKEY correctly; but the PAYREC
  157.    initializations need to be recoded.  If it isn't vital to
  158.    initialize the memory with the specific definition values, you
  159.    could recode the first PAYREC as:
  160.  
  161.    DB  ((TYPE PAYREC) * 3) DUP ?
  162.  
  163.    If you must initialize values, you do so line by line:
  164.  
  165.    DB 'Eric         '
  166.    DW ?
  167.  
  168.    If there are many such initializations, you could define a
  169.    macro INIT_PAYREC containing the DB and DW lines.
  170.                                                              12-4
  171.  
  172. 7. A86 does not support a couple of the more exotic features of
  173.    MASM assembly language: the RECORD directive and its
  174.    associated operators WIDTH and MASK; and the usage of
  175.    angle-brackets to initialize structure records.  These
  176.    features would have added much complication to the internal
  177.    structure of symbol tables in A86; degrading the speed and the
  178.    reliability of the assembler.  I felt that their use was
  179.    sufficiently rare that it was not worth including them for
  180.    compatibility.
  181.  
  182.    If your old program does use these features, you will have to
  183.    re-work the areas that use them.  Macros can be used to
  184.    duplicate the record and structure initializations.  Explicit
  185.    symbol declarations can replace the usage of the WIDTH and
  186.    MASK operators.
  187.  
  188.  
  189. Compatibility symbols recognized by A86
  190.  
  191. A86 has been programmed to ignore a variety of lines that have
  192. meaning to Intel/IBM/MASM assemblers; but which do nothing for
  193. A86.  These include lines beginning with a period (except .RADIX,
  194. which is acted upon), percent sign, or dollar sign; and lines
  195. beginning with ASSUME, INCLUDE, PAGE, SUBTTL, and TITLE. If you
  196. are porting your program to A86, and you wish to retain the
  197. option of returning to the other assembler, you may leave those
  198. lines in your program.  If you decide to stay with A86, you can
  199. remove those lines at your leisure.
  200.  
  201. In addition, there is a class of symbols now recognized by A86 in
  202. its .OBJ mode, but still ignored in .COM mode.  This includes
  203. NAME, END, and PUBLIC.
  204.  
  205. Named SEGMENT and ENDS directives written for other assemblers
  206. are, of course, recognized by A86's .OBJ mode.  In non-OBJ mode,
  207. A86 treats these as CODE SEGMENT directives.  A special exception
  208. to this is the directive
  209.  
  210.     segname SEGMENT AT atvalue
  211.  
  212. which is treated by A86 as if it were the following sequence:
  213.  
  214.     segname EQU atvalue
  215.     STRUC
  216.  
  217. This will accomplish what is usually intended when SEGMENT AT is
  218. used in a program intended to be a COM file.
  219.                                                              12-5
  220.  
  221. Conversion of A86 Programs to Intel/IBM/MASM
  222.  
  223. I consider this section a bit of a blasphemy, since it's a little
  224. silly to port programs from a superior assembler, to run on an
  225. inferior one.  However, I myself have been motivated to do so
  226. upon occasion, when programming for a client not familiar with
  227. A86; or whose computer doesn't run A86; who therefore wants the
  228. final version to assemble on Intel's assembler.  Since my
  229. assembler/debugger environment is so vastly superior to any other
  230. environment, I develop the program using my assembler, and port
  231. it to the client's environment at the end.
  232.  
  233. The main key to success in following the above scenarios is to
  234. exercise supreme will power, and not use any of the wonderful
  235. language features that exist on A86, but not on MASM. This is
  236. often not easy; and I have devised some methods for porting my
  237. features to other assemblers:
  238.  
  239. 1. I hate giving long sequences of PUSHes and POPs on separate
  240.    lines.  If the program is to be ported to a lesser assembler,
  241.    then I put the following lines into a file that only A86 will
  242.    see:
  243.  
  244.       PUSH2 EQU PUSH
  245.       PUSH3 EQU PUSH
  246.       POP2 EQU POP
  247.       POP3 EQU POP
  248.  
  249.    I define macros PUSH2, PUSH3, POP2, POP3 for the lesser
  250.    assembler, that PUSH or POP the appropriate number of
  251.    operands.  Then, everywhere in the program where I would
  252.    ordinarily use A86's multiple PUSH/POP feature, I use one or
  253.    more of the PUSHn/POPn mnemonics instead.
  254.  
  255. 2. I refrain from using the feature of A86 whereby constants with
  256.    a leading zero are default-hexadecimal.  All my hex constants
  257.    end with H.
  258.  
  259. 3. I will usually go ahead and use my local labels L0 through L9;
  260.    then at the last minute convert them to a long set of labels
  261.    in sequence: Z100, Z101, Z102, etc.  I take care to remove all
  262.    the ">" forward reference specifiers when I make the
  263.    conversion.  The "Z" is used to isolate the local labels at
  264.    the end of the lesser assembler's symbol table listing. This
  265.    improves the quality of the final program so much that it is
  266.    worth the extra effort needed to convert L0--L9's to Z100--
  267.    Zxxx's.
  268.  
  269. 4. I will place declarations B EQU DS:BYTE PTR 0 and W EQU
  270.    DS:WORD PTR 0 at the top of the program.  Recall that A86 has
  271.    a "duplicate definition" feature whereby you can EQU an
  272.    already-existing symbol, as long as it is equated to the value
  273.    it already has.  This feature extends to the built in symbols
  274.    B and W, so A86 will look at those equates and essentially
  275.    ignore them.  On the old assembler, the effect of the
  276.    declarations is to add A86's notation to the old language.
  277.    Example:
  278.                                                              12-6
  279.  
  280.      B EQU DS:BYTE PTR 0
  281.      W EQU DS:WORD PTR 0
  282.      MOV AX,W[0100]       ; replaces MOV AX, DS:WORD PTR 0100
  283.      MOV AL,B[BX]         ; replaces MOV AL, DS:BYTE PTR [BX]
  284.  
  285.