home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / LOVE4TH.ZIP / RPN-ASM.DOC < prev    next >
Encoding:
Text File  |  1991-10-01  |  12.5 KB  |  286 lines

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