home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / forth / compiler / love / chap13.doc < prev    next >
Text File  |  1993-04-11  |  19KB  |  430 lines

  1. Chapter13               L.O.V.E. FORTH
  2.  
  3.  
  4.  
  5. 13.0 Third Party Assembler Interface and Linker
  6.      ------------------------------------------
  7.  
  8.          Traditionally in Forth systems, a "Forth Assembler" has been
  9. included.  Adding assembler components to high-level language can produce
  10. dramatic improvements in performance and capability over high-level Forth.
  11. Unfortunately, these assemblers are usually written in Forth, and have
  12. serious limitations. Often the syntax is markedly different from the
  13. expected syntax for the particular processor.  It is usually difficult
  14. enough for most programmers to work in normal assembler syntax, without
  15. having to learn a new one.
  16.  
  17.  
  18.          L.O.V.E. Forth has been designed to use virtually any third party
  19. assembler, using standard assembler syntax.  Whenever   CODE   ;CODE   or
  20. ASM   is encountered, Forth calls in the third party assembler to process
  21. the word, and links in the resulting object file, with a built-in linker.
  22. This means that not only can normal syntax be used in words created by the
  23. programmer, but that assembly language program sections from other sources
  24. can be included with little or no modification.
  25.  
  26.          The authors recommend the excellent assember A86 by Isaacson, also
  27. available as shareware.  The original L.O.V.E. Forth   RPN  assembler is
  28. included with the system as source code, to be used, if desired.
  29.  
  30.  
  31. 13.1 Operation
  32.      ---------
  33.  
  34.     A small amount of set-up is required in order to configure the
  35. system. The authors have already included configuration files for A86,
  36. Microsoft's MASM   and Borland's   TASM   (see Assember Set-up below).  For
  37. simple code words, like those supported by the old   RPN   assemblers, use
  38. is straightforward. For example, a word to make four copies of the top of
  39. stack:
  40.  
  41.         CODE DUP4 ; ( n -- n,n,n,n )
  42.                 pop ax
  43.                 push ax  ; push some copies
  44.                 push ax
  45.                 push ax
  46.                 push ax
  47.                 next c;
  48.         The operation NEXT above is a pre-defined macro.
  49.  
  50.          There are many other powerful features of this facility, namely,
  51. the use of declarations in the assembly code.  Not only can machine code be
  52. assembled, but any other type of data, including threads, heads, and data.
  53. Words can be defined using   PUBLIC   and existing words can be referenced
  54. with   EXTRN.  These are all interpreted by the linker portion of this
  55. interface.
  56.  
  57.  
  58. 13.2 Errors during assembly
  59.      ----------------------
  60.  
  61.          If the assembler fails to produce an object file, an error message
  62. is displayed, and compilation is aborted.  The programmer must then examine
  63. the error or listing file mentioned in the error message, in order to
  64. determine the problem.  The file containing the code to assemble is usually
  65. called  CODE-4TH.ASM, and the file with the errors is usually named
  66. CODE-4TH.ERR or CODE-4TH.LST.
  67.  
  68.  
  69.  
  70. 13.3 SEGMENT Declarations
  71.      --------------------
  72.  
  73.          The linker supports several reserved segment and class names, for
  74. use in directing code into various segments.  These are:  'CODE',
  75. 'THREADS', 'DATA',   'HEADS',   and  'STACKS'.   These reserved names can
  76. either be used as segment, names (most common), or as class names.  When
  77. used as segment names, any class name then specified is ignored.
  78.  
  79.          The following segments are declared automatically for the
  80. programmer at the beginning of each assembly.  The programmer need only
  81. switch between them (eg.   HEADS SEGMENT   is sufficient to switch to
  82. heads, without all the other parts of the declaration).
  83.  
  84.         code    segment byte public 'CODE'
  85.         code ends
  86.         threads segment word public 'THREADS'
  87.         threads ends
  88.         data    segment byte public 'DATA'
  89.         data ends
  90.         heads   segment byte public 'HEADS'
  91.         heads ends
  92.         stacks  segment byte public 'STACKS'
  93.         stacks ends
  94.  
  95.          The code segment is the default, if no other is specified, allowing
  96. simple words to assemble with no declarations whatsoever.  There is a
  97. statement   CODE SEGMENT  automatically inserted before the assembler
  98. statements, and the statements   CODE ENDS  and  END  after the end of the
  99. assembler word.  The directive:
  100.         ASSUME CS:CODE, DS:CODE, ES:CODE
  101. is also inserted, so no segment overrides will be inserted by the
  102. assembler, unless the programmer explicitly includes them.
  103.  
  104.  
  105. 13.4 Origins
  106.      -------
  107.  
  108.     When any segment is declared in an assembler, the origin is assumed
  109. to be 0.  This is fine, when the only code being dealt with is produced by
  110. the assembler; the programmer is in complete control.  Here the code must
  111. be loaded on top of an existing program - L.O.V.E. Forth.  Therefore, the
  112. origins have been constructed to follow a slightly different pattern.
  113.  
  114.          When a reserved name is used for a segment name, the real segment
  115. origin is at 0000 in the L.O.V.E. Forth segment.  The origin (if any) given
  116. by the programmer is incremented by  HERE  (or CS:HERE, TS:HERE, etc),
  117. prior to the code being loaded in.  This ensures that there are no
  118. overwritten areas of memory.  Alignment attribute is not meaningful for
  119. standard  segments; they already start on even byte, word, paragraph and
  120. page boundaries.
  121.  
  122.  
  123.          Should the programmer desire an origin of 0, in the segment being
  124. declared, a different name (unreserved) should be used.  In this case, the
  125. linker looks to the class name for direction, on where to load the code
  126. into memory.  If the class name is not specified, the code is loaded into
  127. the CODE segment.  The alignment type may be specified, if so desired; the
  128. combine type is ignored.
  129.  
  130.  
  131. 13.5 SEGMENT Examples
  132.      ----------------
  133.  
  134.  The most common declaration is:
  135.         CODE SEGMENT
  136.         which causes the code following it to be placed in the code
  137.         segment. The origin coming in from the object file (normally
  138.         0 for the first code in that segment) is incremented by the
  139.         dictionary pointer. Therefore the ORG is forced to be CS:HERE
  140.  
  141.         Another more complex example is:
  142.         MYTHREADS SEGMENT WORD PUBLIC 'THREADS'
  143.         which causes the following code to be loaded into the thread
  144.         segment. The origin is relative to the start of this declared
  145.         segment.
  146.  
  147.         MYSEG SEGMENT
  148.         Code/data in this segment has its own origin of 0.
  149.         If grouped, however, it has an offset from the start of the
  150.         group  <=64k.  It is placed in ram in one of the standard
  151.         segments (in this case the code segment)
  152.  
  153.         THREADS SEGMENT byte public 'code'
  154.         The segment and class conflict - in this case, the class is
  155.         ignored.
  156.  
  157.  
  158. 13.6 GROUP Declaration
  159.      -----------------
  160.  
  161.     The programmer may declare any group, that does not group different
  162. L.O.V.E. Forth segments together (can't because >=64k apart).   A segment
  163. may be part of only one group.
  164.  
  165.         EXTRN declarations
  166.  
  167.         The address or value of existing Forth words may be referenced in
  168. the assembler code, using the   EXTRN   declaration. Since words in
  169. L.O.V.E. Forth have several parts, the address of each part may be
  170. obtained, by adding a special prefix to the name desired. The prefixes are
  171. sorted out by the linker.
  172.  
  173.         Prefix                  Segment         Purpose
  174.                                 Register
  175.         CODE@  (no prefix)      CS      address of machine code
  176.         THREADS@                DS      compilation address
  177.         DATA@                   ES      parameter field address
  178.         HEADS@                  n/a     name field address
  179.         IMMEDIATE@              n/a     special - executes the
  180.                                         following word at link-time to
  181.                                         obtain value
  182.  
  183.         For example:
  184.  
  185.         EXTRN CODE@COUNT:NEAR, DATA@TIB:BYTE, IMMEDIATE@HERE:ABS
  186.  
  187.         MOV BYTE PTR ES:DATA@TIB, 0DH ; install carriage return
  188.         ADD AX,IMMEDIATE@HERE         ; add HERE
  189.         JMP CODE@COUNT                ; exit via a forth word
  190.  
  191.  
  192.          If the word appears without a prefix or if CODE@ is in front of the
  193. word, then the address of the related machine code is returned.  This is
  194. the same as is returned with   'CODE .   Similarly   THREADS@ returns the
  195. compilation address of the following word.  The most useful prefix is
  196. perhaps   DATA@   which returns the parameter field address, the address
  197. returned by a   VARIABLE   or other word created by   CREATE.  HEADS@
  198. returns the name field address.   This is relative to the head segment, the
  199. actual value of which can be obtained from the label   HSEG   (see Frame
  200. Fixups below).
  201.  
  202.          The word IMMEDIATE@ can execute a word at link-time.  This is
  203. typically a   CONSTANT   whose value is required, or a   VARIABLE   whose
  204. address is required in assembly code  ( eg. IMMEDIATE@BL ). It can be any
  205. word that returns a single cell on the stack. If   HERE  or the other
  206. dictionary values are referenced, they return the values they had, prior to
  207. linking.
  208.  
  209.          If using   MASM  the programmer must pay particular attention to
  210. how the external references are declared. When using the reference as a
  211. memory pointer (eg. BYTE PTR ) the reference must be declared as :BYTE   or
  212. :WORD   (or other address delaration).  A value used as an immediate type
  213. operand must be declared :ABS .  If mis-declared,   MASM ignores the
  214. addressing mode explicitly used in the instruction, in favour of what is
  215. implied in the   EXTRN   declaration.  A reference can, therefore, not be
  216. used both as an immediate type operand and a memory reference.
  217.  
  218.  
  219.         If using A86, the programmer need not include the   EXTRN
  220. directive, as any symbols that are undefined, are automatically declared
  221. external. And if the   EXTRN   directive is used any type declaration
  222. (:NEAR, :WORD, :ABS, etc.) may be used, A86 handles all cases correctly.
  223.  
  224.  
  225. 13.7 Forth Words with Illegal Characters
  226.      -----------------------------------
  227.  
  228.          When words contain characters that are illegal for the assembler, a
  229. prefix of %% may be used. This prefix is dealt with before assembly begins,
  230. and changes the name to one acceptable for the assembler. Illegal
  231. characters include:  +-*/%^() and many more.  The word prefixed by %% must,
  232. however, be terminated by a space, tab or end of line.  For example:
  233.  
  234.         %%-TRAILING         %%+!     %%2DUP
  235.  
  236.         Complete example, a word which exits via */
  237.  
  238.         CODE 550_337_*/ ; ( scale n by this fraction to get m ( n -- m )
  239.            extrn %%*/ :near  ; reference to the word */
  240.            mov ax,550
  241.            push ax
  242.            mov ax,337
  243.            push ax
  244.            jmp %%*/ c;
  245.  
  246.  
  247. 13.8 PUBLIC declarations
  248.      -------------------
  249.          Just as it is possible to reference Forth words from within
  250. assember with   EXTRN,   it is also possible to create new words. This is
  251. done with the   PUBLIC  directive. This can be used to create multiple
  252. entry points in words, or simply to create address references available in
  253. high level code or other code definitions. The %% prefix described above,
  254. can be used to make names with assembler-illegal characters.  Example:
  255.  
  256.         CODE QDROP ; ( q -- )
  257.               POP AX  ; yes, there are more efficient ways of coding
  258.               POP AX  ;        this word
  259.         DDROP:POP AX
  260.         DROP: POP AX
  261.               NEXT
  262.  
  263.         PUBLIC DDROP ; ( d -- )
  264.         PUBLIC DROP  ; ( n -- )
  265.         c;
  266.  
  267.          As shown in the table below,  PUBLIC   declarations work
  268. differently, depending on which segment the label is declared in.  Note
  269. that a reference to the data segment, effectively becomes a   VARIABLE .
  270.  
  271.         code segment            A CODE word is created
  272.         threads segment         The PUBLIC address is assumed to be
  273.                                     the compilation address of a word
  274.         other segment           A CONSTANT is created with the value
  275.            names                    of the PUBLIC address
  276.  
  277.  
  278.         A PUBLIC Caution about FORGET
  279.  
  280.          Words declared   PUBLIC   are   CREATED  at link-time.
  281. Unfortunately, most linkers do not provide PUBLIC declarations in any
  282. reasonable order. This means that a word declared later, may refer to a
  283. word lower in memory.  This conflicts with  FORGET  which removes
  284. everything above the forgotten word. When using  FORGET, be sure to forget
  285. all of the words PUBLIClTY  CREATED  within one code word or  ASM  section.
  286.  
  287.  
  288.  
  289. 13.9 The Command ASM
  290.      ---------------
  291.  
  292.     ASM   is the best way to include a large body of assembly code into
  293. Forth.  ASM   simply begins a section of assembly language code.  There is
  294. no word   CREATED  like  CODE ,   Words that require access from high-level
  295. Forth or other assembler words, should be declared   PUBLIC   as described
  296. above. Many code words can thus be included in one section.  Example:
  297.  
  298.         ASM
  299.         code segment
  300.         BIT:   ; ( access a table of bits ( n -- bit )
  301.                 POP BX
  302.                 ADD BX,BX
  303.                 PUSH es: [BX+bittable]
  304.                 NEXT
  305.         code ends
  306.  
  307.         data segment
  308.         assume cs:data
  309.         bittable: dw 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192
  310.                   dw 16384,32768
  311.         data ends
  312.         PUBLIC BIT
  313.              end c;
  314.  
  315.  
  316. 13.10 Linking Object Files
  317.       --------------------
  318.  
  319.  
  320.          The linker is automatically started after assembling a code word
  321. with   CODE   ;  CODE   or   ASM .  It is also possible for the linker to
  322. operate on existing object files.  The authors may also be delivering
  323. object file versions of utilities and upgrades in the future.  The syntax
  324. for this commmand is   LINK" followed by the path and file name of a
  325. Microsoft format OBJ file.
  326.  
  327.    For example:
  328.               LINK" MATRIX.OBJ"
  329.         Would link in the specified file.
  330.  
  331.  
  332. 13.11   Assembler Set-up
  333.         ----------------
  334.  
  335.          Three assemblers are currently supported directly.  A86, Microsoft
  336. MASM   version 5,   MASM   version 6 and Borland TASM.  In order to use one
  337. of these, the configuration file must be copied to the name  ASSEMBLY.CFG,
  338. for example to use A86 type:  COPY LOVEA86.CFG  ASSEMBLY.CFG for   MASM,
  339. MASM 6  and  TASM,  the files are   LOVEMASM.CFG   LOVEML6.CFG and
  340. LOVETASM.CFG   respectively.   MASM   version 6 takes so much memory that
  341. the extended memory version must be used.  This only works if you omit
  342. EMM386.
  343.  
  344.          If using another assembler, any of the above files can be modified
  345. according to what the assembler needs. Read the instructions in the CFG
  346. files (standard ascii).  The following information must be provided:
  347.  
  348.         command line
  349.         input, output, listing, error files
  350.         the macro definition for   NEXT
  351.         the segment declarations
  352.  
  353.         lines to precede the lines parsed from   CODE   or   ;CODE
  354.         lines to follow the lines from   CODE  or   ;CODE
  355.  
  356.  
  357.          When the assembly file is created, first the macro definition, then
  358. the segment declarations described above are inserted into the file, along
  359. with the name of the word being assembled (if applicable). If assembling
  360. the words   CODE   or   ;CODE,  the "line to preceding" those parsed above
  361. are inserted, then the lines between CODE   (;CODE)   and C;.   The file is
  362. terminated with the "lines to follow" from above.  If the command   ASM  is
  363. used, the lines between  ASM and C; are inserted following the segment
  364. declarations, and the file is terminated.
  365.  
  366.  
  367. 13.12 Improving performance
  368.       ---------------------
  369.          This method of assembly can be slow on any machine. The act of
  370. calling another program (assembler) through DOS is time consuming,
  371. especially in disk accesses. There are two ways to speed this up:
  372.  
  373.         1. Use the ASM facility to group   CODE   words together.  The
  374.            words which would otherwise have been declared separately
  375.            will all be declared at one time, using the   PUBLIC
  376.            declaration. The assembler is only invoked once per   ASM
  377.            section.
  378.  
  379.         2. Create a small   RAM   disk to include the temporary files
  380.            listed in   ASSEMBLY.CFG   (just change the drive and/or
  381.            directory where these are stored). For most words a size of
  382.            30k should be more than enough. The assembler itself can
  383.            also be copied to the   RAM   disk if it is big enough.
  384.  
  385.  
  386. 13.13 Frame Fixups
  387.       ------------
  388.  
  389.          Frame fixups are not supported. This means that explicit references
  390. to segments are not allowed. Keep in mind that, on entry to any code word,
  391. the segment registers contain the usual segment values. In addition, there
  392. are locations defined in the  CS: (CODE segment)   that contain the current
  393. addresses of the standard segments.  (These are   CONSTANTS).
  394.  
  395. Address         contains segment value          also in register
  396. CSEG            CODE                            CS
  397. TSEG            THREADS                         DS
  398. VSEG            DATA                            ES
  399. SSEG            STACKS                          SS
  400. HSEG            HEADS                           n/a
  401. PSPSEG          DOS program segment prefix      n/a
  402.  
  403.         So access to these values is via the CS register, for example,
  404.         to load the VS value into DS:
  405.  
  406.                 MOV DS, word ptr CS: IMMEDIATE@VSEG
  407.  
  408. 13.14 Why frame fixups are not supported:
  409.       -----------------------------------
  410.  
  411.  
  412.     In order to be used interactively, any frame numbers included in
  413. code would have to be resolved immediately on assembly.  This is not a
  414. problem; the problems occur later. When an application is   SAVED   and
  415. then re-executed at a later time, the location in memory where DOS loads
  416. the program is often different.  Relocation is supported by DOS; the   EXE
  417. file header can contain relocation items.  However, when the program is
  418. SAVED, the segment memory images are concatenated and the result is saved
  419. in the   EXE   file.  It is difficult to determine both where the fixup
  420. locations are, and where they are to point to, since on  re-execution the
  421. image is expanded again.  In addition, before the image  is to be saved,
  422. these references would have to be de-relocated.  Not completely impossible,
  423. but difficult.  Further difficulties ensue if the program is saved as a
  424. final   APPLICATION,   where the program is both saved and executed in its
  425. concatenated form.
  426.  
  427.      A version of L.O.V.E. Forth in preparation is able to perform frame
  428. fixups (the fixup information is stored as a field in each dictionary
  429. head).  When saving an application with   APPLICATION"   these data are
  430. transferred to the .EXE header.