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

  1. Chapter14               L.O.V.E. FORTH
  2.  
  3.  
  4.  
  5. 14.0 RPN Assembler
  6.      -------------
  7.  
  8.     This is a classic Forth assembler that utilizes   RPN   syntax.
  9. During assembly, the arguments and opcodes are executed to produce
  10. instructions which are added to the code segment.  Those who prefer normal
  11. assembler syntax should use the newer third party assembler facility.  This
  12. RPN assembler is included only for older code, or code appearing on
  13. screens.
  14.  
  15.     Though this assembler is large, this penalty is minimized by
  16. including it as a virtual vocabulary.  When the interpreter encounters
  17. either the  word   CODE   or   ;CODE, the assembler will be called into
  18. upper memory and the assembling of code will start.  When no longer needed,
  19. it can be removed by the word   FORGET-SYS.  It is automatically removed by
  20. SAVE"   or any word that calls another virtual subsystem.
  21.  
  22.     It is assumed that the user has access to an 8086/8088 handbook
  23. such as:  "iAPX 86,88 User's Manual" by Intel Corporation or "THE 8086 BOOK
  24. includes the 8088" by R.Rector and G.Alexy, OSBORNE/McGraw-Hill (though the
  25. latter has many errors).
  26.  
  27.  
  28. 14.1 Using the RPN assembler
  29.      -----------------------
  30.  
  31.     Normally the external assembler/linker is provided for assembling
  32. code. In order for the RPN assembler to be used, it must be loaded in. The
  33. source code is provided for this.  Type the following:
  34.     INCLUDE"   LOADRASM.TXT"   (enter)
  35. To make the change permanent, simply save the forth system with
  36.     SAVE"   filename.EXE"
  37.  
  38.  
  39. 14.2 Format for Code Words
  40.      ---------------------
  41.     Assembling is initiated by either   CODE   or   ;CODE   and
  42. terminated by  C;  (or its alias  END-CODE ).   The exit point(s) in a code
  43. NEXT-JMP   assembles the following in-line code:
  44.  
  45.            WORD LODS  BX, AX MOV  WORD [BX] JMP
  46.  
  47. The following are examples of usage:
  48.  
  49. CODE U/MOD BX POP  DX POP  AX POP  DX, BX CMP
  50.            IFU<  BX DIV DX PUSH APUSH-JMP
  51.            THEN  AX, # -1 MOV  AX PUSH  APUSH-JMP C;
  52.  
  53. : CONSTANT CREATE: TS:,
  54.     ;CODE
  55.            2 [BX] PUSH  NEXT-JMP C;
  56.  
  57.  
  58. 14.3 Logical Operators
  59.      -----------------
  60.     Logical operators have been added to the Assembler to simplify
  61. writing and reading the assembly code.  They also obviate labels and
  62. forward referencing.  The logical test words can be used after any
  63. operation code, that causes the appropriate status flags to be set or
  64. cleared; i.e.  CMP   CMPS   OR    ADD   SUB   etc.
  65.  
  66.     With the exception of   REPEAT   and   AGAIN ,  which assemble
  67. unconditional signed relative two-byte jumps, these logical operators
  68. assemble one-byte jumps.  The assembler will detect an attempt to assemble
  69. an  out-of-range jump, and will print an appropriate error message, and
  70. stop assembling.
  71.  
  72.  
  73.         DO .. LEAVE .. LOOP.   This construct differs from the high-level
  74. FORTH construct in that only one argument is used.  The  CX  register must
  75. contain the count upon reaching   LOOP.  The   LEAVE operation will set the
  76. CX register to 1 which is first decremented upon reaching LOOP; then, an
  77. exit from the   LOOP   is made if the  CX register is 0.  If the  CX
  78. register is not 0 upon reaching   LOOP,  the program counter will be set to
  79. the instruction just after  DO.  The count placed in the  CX register  can
  80. vary from 1 to FFFF (65535 decimal).  The following is a simple
  81. illustration of usage:
  82.  
  83. ( starting at addr, searches n bytes for char)
  84. ( addr  n  char  ---  addr -1  or  0 )
  85. CODE CHARSRCH
  86.      AX POP  CX POP  DX, DI MOV  DI POP
  87.      DO  SCAS
  88.         IF= DI DEC  DI PUSH  DI, DX MOV  AX, # -1 MOV  APUSH-JMP
  89.         THEN
  90.      LOOP  CX PUSH  DI, DX MOV  NEXT-JMP C;
  91.  
  92.     The sequence:     IF=
  93.             IF<
  94.             IF0<
  95.             IFU< ... ELSE ... THEN
  96. will calculate the relative one-byte jumps and assemble the appropriate
  97. code, ie.  JNZ    JNL    JNB    or   JMP .    The IF operators can be used
  98. after any operation that sets the appropriate flags.  (Note that
  99. AX, AX OR   has the same effect as AX, # 0 CMP but requires one less cycle).
  100.  
  101.     If the logical test is immediately followed by the word 'non'
  102. ('not' was not used to avoid conflict with the  NOT  op code), the test is
  103. negated.  For example,  AX, BX CMP  IF= non ... would perform the operation
  104. following IF=  if the  AX  and the  BX  registers were not equal.
  105.  
  106. The following are examples of usage.
  107.  
  108. CODE MAX  AX POP  BX POP  AX, BX CMP
  109.           IF< BX PUSH  ELSE  AX PUSH  THEN NEXT-JMP C;
  110.  
  111. CODE U<   CX POP  BX POP  AX, AX XOR  BX, CX CMP
  112.           IFU< AX DEC THEN  APUSH-JMP C;
  113.  
  114. CODE ABS  AX POP  AX, AX OR
  115.           IF0< AX NEG THEN  APUSH-JMP C;
  116.  
  117. CODE DIGIT DX POP  BX POP  AX, AX XOR  BL, # 48 SUB
  118.           IF< non  BL, # 10 CMP
  119.              IF< non BL, # 7 CMP
  120.                 IF<  APUSH-JMP THEN
  121.              THEN BL, DL CMP
  122.              IF< AX DEC  DX, DX XOR DL, BL MOV  DX PUSH
  123.              THEN
  124.           THEN APUSH-JMP C;
  125.  
  126.     In a similar manner, the following logical sequences will compile
  127. the appropriate offsets and jump codes.
  128.  
  129. BEGIN .. AGAIN
  130. BEGIN .. UNTIL= (or) UNTIL< (or) UNTILU< (or) UNTIL0<
  131. BEGIN .. WHILE= (or) WHILE< (or) WHILEU< (or) WHILE0< ... REPEAT
  132.  
  133.  
  134.     Because the operation code word   TEST   produces a logical result,
  135. that appears to be the reverse of the foregoing conditional branch words, a
  136. separate set of words are provided to replace them, namely:   IFTEST
  137.  IFNOTEST,   WHILETEST,   WHILENOTEST.    Do not use the word 'non' to
  138. negate these words. For example   IFNOTEST   is the negative of  IFTEST.
  139.  
  140.     The following word from the   EDITOR   illustrates a combined usage
  141. of these operators.  The word <#SPCS?> will determine the number of blank
  142. spaces at the end of a 64 character line on the display.  The operation is
  143. performed during retrace cycles.
  144.  
  145. ( L#ADDR X-offset llength -- n )
  146. CODE <#SPCS?>
  147.   -2 [BP], DI MOV
  148.   CX POP  AX POP  AX, CX ADD  AX, 1 SHL  AX DEC
  149.   DI POP  ES PUSH  ES: DX, CRTPORT MOV  ES: ES, CRTSEG MOV
  150.   DI, AX ADD  BX, BX XOR  STD
  151.    BEGIN  DI DEC  CX DEC
  152.       BEGIN  AL, DX IN  AL, # 1 TEST  UNTILNOTEST  CLI
  153.       BEGIN  AL, DX IN  AL, # 1 TEST  UNTILTEST    AL, # 20 MOV  SCAS
  154.       IF=  BX INC  ELSE  CX, CX XOR  THEN  CX, # 0 CMP
  155.    UNTIL=  CLD  STI  ES POP  BX PUSH
  156.    DI, -2 [BP] MOV  NEXT-JMP C;
  157.  
  158.  
  159. 14.4 Assembler Addressing
  160.      --------------------
  161.  
  162.     The following nomenclature is used in defining the arguments for
  163. the assembler operation codes:
  164.  
  165.         ac      = AX or AL
  166.  
  167.         reg     = AX AH AL BX BH BL CX CH CL DX DH DL SI DI BP or SP
  168.  
  169.         mem/reg = any register, a direct memory address,
  170.                   [BX+SI] [BX+DI] [BP+SI] [BP+DI] [SI] [DI]
  171.                   [BX] [BP], or any bracketed expression plus a
  172.                   preceding displacement.
  173.  
  174.         port    = a number, 0 through FFFF (hex)
  175.  
  176.         data    = a number, 0 through FFFF (hex)
  177.  
  178.         segreg  = CS DS ES or SS
  179.  
  180.         size    = BYTE  or WORD  (if unspecified, BYTE is assumed)
  181.  
  182.         n       = 0 to FF (hex)
  183.  
  184.  
  185. 14.5 Assembler operation codes
  186.      -------------------------
  187.  
  188.     On the following page are the operation codes that can be assembled
  189. by the assembler, and the required formats for the arguments.  Note that
  190. the symbol # followed by a space must precede data.  Also, when two
  191. arguments are used, they must be separated by a comma followed by a space.
  192. If a register is the first argument, the comma is part of the register
  193. label, eg:
  194.  
  195.                 AX, BX MOV
  196.     If the first argument is a number for a port or an address, a space
  197. must precede the comma, eg.
  198.                 0FE42 , BX MOV.
  199.  
  200.     Where there is a one-byte versus two-byte ambiguity, the default is
  201. one byte. To force a two-byte operation, precede the operation code with
  202. the word  WORD   eg.
  203.                 WORD [BX] NEG.
  204.  
  205.     Note that when using addresses with   JMPs   and   CALLs   the best
  206. size offset (8 or 16 bit) is selected by the assembler.  To specify
  207. intersegment  JMPs,  CALLs  +RETs  and RETs  the prefix FAR is used.
  208.  
  209.    For example:
  210.  
  211.     to perform an intersegment indirect branch, the following sequence
  212.     is used:
  213.  
  214.          FAR  [BX]  JMP
  215.     When   FAR   is not used an intrasegment branch is assumed.
  216.  
  217.  
  218.     Segment overrides are specified by placing  CS:  DS:  ES:  or  SS:
  219. in front of the operation they are to modify.
  220.  
  221. Before exiting from a code word via   NEXT-JMP   you must restore the
  222. following registers to the values they had upon entry to the routine:
  223.                 SI, DI
  224.                 CS, DS, SS, ES
  225. The flags DF, IM must both be restored with the instructions:
  226.                 STI and CLD.
  227. The following registers must not have unreasonable changes:
  228.                 SP, BP
  229. For more information on register usage see the implementation notes.
  230.  
  231.  
  232. 14.6 Assembler LABELs
  233.      ----------------
  234.  
  235.     In order to create branching or other labels within a code word,
  236. the declaration   LABEL   can be used.  This creates a  CONSTANT based on
  237. the current code segment dictionary pointer.  This can be refered to in
  238. high-level Forth.  This relies on the L.O.V.E. Forth characteristic, that
  239. CONSTANTS only add code to the thread and head segments.
  240.  
  241.       Example:
  242.  
  243.      CODE S>D        ( signed conversion ( n -- d )
  244.         AX POP  CWD
  245.          LABEL DXAX-PUSH ( push dx and ax )
  246.           DX PUSH  AX PUSH  NEXT-JMP C;
  247.  
  248. CODE D2*   ( double double ( d-- d)
  249.    AX POP  DX POP  DX, 1 SHL  AX, 1 ROL  DXAX-PUSH JMP C;
  250.  
  251.  
  252. 14.7 Operation Codes
  253.      ---------------
  254.  
  255.       AAA                     AAD                     AAM
  256.                 AAS
  257.      ac, # data ADC     mem/reg, # data ADC *  mem/reg, mem/reg ADC
  258.      ac, # data ADD     mem/reg, # data ADD *  mem/reg, mem/reg ADD
  259.      ac, # data AND     mem/reg, # data AND *  mem/reg, mem/reg AND
  260.        address CALL            mem/reg CALL                     CBW
  261.                 CLC                     CLD                     CLI
  262.                 CMC
  263.      ac, # data CMP     mem/reg, # data CMP *  mem/reg, mem/reg CMP
  264.           size CMPS                     CWD                     DAA
  265.                 DAS                 reg DEC             mem/reg DEC *
  266.         mem/reg DIV *                   HLT            mem/reg IDIV *
  267.        mem/reg IMUL *             ac, DX IN             ac, port IN
  268.             reg INC             mem/reg INC *                 n INT
  269.                INTO                    IRET
  270.          address JA             address JAE              address JB
  271.         address JBE            address JCXZ              address JE
  272.          address JB             address JGE              address JL
  273.         address JLE             address JMP             mem/reg JMP
  274.         address JNA            address JNAE             address JNB
  275.        address JNBE             address JNE             address JNG
  276.        address JNGE             address JNL            address JNLE
  277.         address JNO             address JNP             address JNS
  278.         address JNZ              address JO              address JP
  279.         address JPE             address JPO              address JS
  280.         address JZ                     LAHF
  281.    reg, mem/reg LDS        reg, mem/reg LES        reg, mem/reg LEA
  282.                LOCK               size LODS            address LOOP
  283.      address LOOPNE          address LOOPNZ           address LOOPZ
  284.     reg, # data MOV     mem/reg, # data MOV *  mem/reg, mem/reg MOV
  285.     ac, address MOV     segreg, mem/reg MOV     mem/reg, segreg MOV
  286.    address , ac MOV               size MOVS             mem/reg MUL *
  287.         mem/reg NEG *                   NOP             mem/reg NOT *
  288.       ac, # data OR      mem/reg, # data OR *   mem/reg, mem/reg OR
  289.          DX, ac OUT           port , ac OUT
  290.             reg POP             mem/reg POP     segreg (not CS) POP
  291.                POPF                   PUSHF
  292.            reg PUSH            mem/reg PUSH             segreg PUSH
  293.      mem/reg, 1 RCL *       mem/reg, CL RCL *
  294.      mem/reg, 1 RCR *       mem/reg, CL RCR *
  295.                 REP                    REPE                   REPNE
  296.               REPNZ                    REPZ                     RET
  297.      mem/reg, 1 ROL *       mem/reg, CL ROL *
  298.      mem/reg, 1 ROR *       mem/reg, CL ROR *
  299.                SAHF
  300.      mem/reg, 1 SAL *       mem/reg, CL SAL *
  301.      mem/reg, 1 SAR *       mem/reg, CL SAR *
  302.      ac, # data SBB     mem/reg, # data SBB *  mem/reg, mem/reg SBB
  303.           size SCAS
  304.      mem/reg, 1 SHL *       mem/reg, CL SHL *
  305.      mem/reg, 1 SHR *       mem/reg, CL SHR *
  306.                 STC                     STD                     STI
  307.           size STOS
  308.      ac, # data SUB     mem/reg, # data SUB *  mem/reg, mem/reg SUB
  309.     ac, # data TEST    mem/reg, # data TEST *     reg, mem/reg TEST
  310.                WAIT            AX, reg XCHG       reg, mem/reg XCHG
  311.                XLAT
  312.      ac, # data XOR     mem/reg, # data XOR *  mem/reg, mem/reg XOR
  313.              n +RET
  314. * these operations require a size   BYTE,  WORD   when the operand is
  315.   a memory location(s).