home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / tp_asm.exe / TP&ASM.REF < prev    next >
Encoding:
Text File  |  1989-07-31  |  52.9 KB  |  1,367 lines

  1.  
  2.   TP&Asm           Integrated Compile-Time Assembler          Version 2.2
  3.  
  4.                 Copyright (c) 1989  Richard W. Prescott
  5.                           All Rights Reserved
  6.  
  7. ═══════ Built-In Assembly Language Support for Turbo Pascal Compilers ═══════
  8.  
  9.  All brand and product names mentioned herein are trademarks or registered
  10.                 trademarks of their respective holders.
  11.  
  12.   ┌─────────────────────────────────────────────────────────────────────┐
  13.   │ This file contains detailed reference information to enable you to  │
  14.   │ make effective use of the TP&Asm assembly environment.  For general │
  15.   │ information on getting started please see the README file.          │
  16.   └─────────────────────────────────────────────────────────────────────┘
  17.  
  18.  
  19. The following topics are described below:
  20.  
  21.     1. Command Line Options
  22.     2. The Assemble Statement
  23.     3. The Asm Statement
  24.     4. The Internal Statement
  25.     5. General Assembler Syntax
  26.     6. TP&Asm-specific Options
  27.     7. Supported Mnemonics
  28.  
  29.  
  30. The following additional topics are covered in the separate file
  31. TP&ASM2.REF:
  32.  
  33.     8. Error Messages
  34.     9. Trouble Shooting
  35.  
  36.  
  37. Information specific to the use of TP&Asm with Turbo Pascal 5.5 
  38. Objects and Methods can be found in the separate file TP&ASM.OOP.
  39.  
  40.  
  41. TP&Asm Version 2.2 fully supports Turbo Pascal Version 5.5 and 
  42. Object Oriented Programming.  In general, any assembly operation
  43. which is valid with a standard Procedure or Function is valid
  44. with a Version 5.5 Method, and any operation which is valid with
  45. a Record is valid with a Version 5.5 Object.  For additional 
  46. information please see the file TP&ASM.OOP.
  47.  
  48.  
  49.  
  50. 1. Command Line Options
  51.  
  52. TP&Asm is invoked by typing one of the following lines at the DOS
  53. prompt:
  54.      tpa <full command line>
  55.      tpa <abbreviation> <options>
  56.      tpa
  57.  
  58. Full Command Syntax:  At the DOS prompt, type
  59.  
  60.      tpa <full command line>
  61.  
  62. where <full command line> is any valid command line that could be 
  63. executed directly from the DOS prompt.  TP&Asm will load into 
  64. memory and then execute the command line, exactly as if it had been 
  65. executed by DOS.  If a supported Turbo Pascal compiler is loaded at 
  66. any point during the execution of the command line, you will see a 
  67. message indicating that the assembler is active, and assembly 
  68. support will be enabled.  TP&Asm will not interfere with the 
  69. operation of other non-compiler applications.  
  70.  
  71. Examples:
  72.  
  73.      tpa mybatch
  74.        run the batch file MYBATCH.BAT which changes directories and
  75.        then runs turbo.  Assembly support will be enabled.
  76.  
  77.      tpa tpc myprog /r"param1 param2"
  78.        run TPC Version 4.0 to compile MYPROG.PAS and run in memory.
  79.        (Please see the Version 4.0 Owner's Handbook for information
  80.        on the /r command line option).  Assembly support will be
  81.        enabled.
  82.  
  83.      tpa c:\command
  84.        load a copy of the command processor and return you to the
  85.        DOS prompt.  You have just made TP&Asm "Memory resident"!
  86.        Now EACH time you run a supported compiler, you will get a
  87.        message indicating that the assembler is active, and
  88.        assembly support will be enabled.  Each time you exit a
  89.        compiler, you will get a message indicating that the
  90.        assembler is inactive.  Type EXIT to quit the command
  91.        processor and remove TP&Asm from memory.  (You should not
  92.        run any RESIDENT programs from the command shell or you will
  93.        not be able to remove it from memory).
  94.  
  95. Abbreviated Syntax:  At the DOS prompt, type one of the following:
  96.  
  97.      tpa c <options>
  98.      tpa d <full command line>
  99.  
  100. tpa c <options> is equivalent to:   tpa tpc <options>,
  101. which runs the command line compiler with the specified options.
  102. Example:
  103.      tpa c myprog         (same as: tpa tpc myprog )
  104. (Please see the Turbo Pascal Owner's Guide for available options).
  105.  
  106. tpa d <full command line> will run any valid DOS command line
  107. through debug with assembly support enabled.  This is primarily of
  108. interest to Turbo Version 4.0 users.  (Requires DEBUG.COM from
  109. your DOS disk).  Examples:
  110.      tpa d turbo          (same as: tpa debug turbo.exe )
  111.      tpa d tpc test /r    (same as: tpa debug tpc.exe test /r )
  112.  
  113. NOTE: the recommended method of using any debugger with TP&Asm is to
  114. run the debugger from TP&Asm:
  115.      TPA <debugger> <parameters required by debugger>
  116. (Please be thoroughly familiar with the proper operation of your
  117. debugger before attempting this, since it is definitely possible to
  118. crash your system through improper use of a debugger.  Save your
  119. work frequently, and be prepared to reboot).
  120.  
  121.  
  122. Quick Command Syntax:  At the DOS prompt, type
  123.  
  124.      tpa
  125.  
  126. TP&Asm will load into memory and then execute TURBO.EXE, exactly as 
  127. if you had typed "turbo" at the DOS prompt.  You will see a message 
  128. indicating that the assembler is active, and assembly support will 
  129. be enabled.  ( This is the same as executing:  tpa turbo ).  
  130.  
  131.  
  132.  
  133.  
  134. 2. The Assemble Statement
  135.  
  136. The syntax for the assemble statement is:
  137.  
  138.     Assemble  <remainder of line must be empty>
  139.  
  140.        <Standard Assembly language statements>
  141.  
  142.     End
  143.  
  144. Use of a semicolon ";" after the final "End" is governed by
  145. standard Pascal statement syntax.  Assembly ends with the first
  146. "End" encountered in the mnemonic field.  The entire line is then
  147. passed on to the compiler, permitting use of an Assemble statement
  148. in either clause of an "IF .. THEN .. ELSE" conditional statement.
  149.  
  150. The keyword "Assembly" is permitted as a synonym for "Assemble".
  151. This is useful to avoid misleading constructions like:
  152.      IF <Pascal Condition> THEN Assemble
  153. which gives the false impression of conditional assembly.  True
  154. conditional assembly is possible using the PAS statement described
  155. in the section TP&Asm-specific options.  Conditional execution of
  156. an assembly block is more clearly indicated by:
  157.      IF <Pascal Condition> THEN Assembly
  158.  
  159. The Assemble statement can be used in any situation where an Inline
  160. statement would be valid, including in the definition of (Assembly)
  161. Inline directive/MACROs.
  162.  
  163. Examples:
  164.  
  165.  {- Conditional execution of assembly code based on runtime value of x: }
  166.   IF x > 0 THEN Assembly
  167.     : <assembly statements>
  168.   End  {without semicolon}  ELSE Assembly
  169.     : <assembly statements>
  170.   End; {requires semicolon}
  171.  
  172.  {- Define an (Assembly) Inline directive/MACRO: }
  173.   PROCEDURE ClearInterrupts;
  174.   Assemble
  175.     Cli
  176.   End; {MACRO ClearInterrupts}
  177.  
  178.  {- Define a callable procedure with assembly code: }
  179.   PROCEDURE PrintScreen;
  180.   BEGIN
  181.     {- Pascal statements may be placed before ... -}
  182.     Assemble
  183.       Int 5
  184.     End; {Assemble}
  185.     {- ... or after the assembly code -}
  186.   END; {PrintScreen}
  187.  
  188.  
  189. Assembly sections may be mixed freely with other Pascal statements
  190. throughout the statement part of a block.  Transfer between Pascal
  191. and assembly sections is freely permitted:
  192.  
  193.  ■ A Pascal label may be specified as the target of any assembly
  194.    Call, Jmp, Loop, or conditional jump.  As with the Pascal "Goto"
  195.    statement, the label must be defined in the current block.
  196.  
  197.  ■ An assembly label may be specified as the target of a Pascal
  198.    "Goto" statement.  The target label must be declared in a
  199.    standard Pascal "Label" statement.  (Assembly labels which are
  200.    referenced only within the current Assemble statement need not
  201.    be declared).
  202.  
  203.  ■ Pascal Procedure and Function identifiers may be specified as
  204.    the target of any assembly Call (or Jmp), or as immediate data
  205.    offsets in assembly data manipulation instructions, eg:
  206.          Mov Dx,PasProc ;load Ofs(PasProc) into Dx
  207.    The Procedure or Function must be defined in the current program
  208.    or in a Unit specified in the Uses clause.  Assembly references
  209.    are fully recognized by the Turbo smart linker.
  210.  
  211.   "System" Procedures and Functions do not use true PROC Calls and
  212.    therefore cannot be called from assembly language, either
  213.    directly or indirectly, except using "PAS" as described below.
  214.  
  215.  ■ The assembly keyword "PAS" may be used to insert single or
  216.    multiple line Pascal statements within an assembly section.
  217.    See the section entitled TP&Asm-specific options.
  218.  
  219. As with the Inline statement, the registers BP, SP, SS, and DS
  220. should be restored before execution of any Pascal statements,
  221. including Procedure calls and "PAS" statements.
  222.  
  223. Please see the numerous .PAS files on the distribution disk
  224. (archive TP-ASM.ZIP, available on CompUServe) for additional
  225. examples of Assemble statement usage.
  226.  
  227.  
  228. 3. The Asm Statement
  229.  
  230. Situations that require only a single line of assembly code
  231. may be more concisely specified using an "Asm" statement.  The
  232. keyword "Asm" is used to instruct the compiler that the remainder
  233. of the current line is to be interpreted as an assembly language
  234. statement, and that the following line is to be interpreted as a
  235. Pascal statement.
  236.  
  237. As with the Assemble statement, the use of a semicolon ";" is
  238. governed by standard Pascal statement syntax, permitting use of
  239. an Asm statement in either clause of an "IF .. THEN .. ELSE"
  240. conditional statement.
  241.  
  242. The Asm statement can be used in any situation where an Inline
  243. statement would be valid, including in the definition of (Assembly)
  244. Inline directive/MACROs.
  245.  
  246. Examples:
  247.  
  248.  {- Single line assembly code in Pascal conditional statement: }
  249.   IF x > 0 THEN Asm Push PasVar1
  250.            ELSE Asm Push PasVar2; {comment permitted here}
  251.  
  252.  {- Define an (Assembly) Inline directive/MACRO: }
  253.   PROCEDURE ClearInterrupts;  Asm Cli;
  254.  
  255.  {- Define a callable procedure with assembly code: }
  256.   PROCEDURE PrintScreen;
  257.   BEGIN
  258.     {- Pascal statements may be placed before ... -}
  259.     Asm Int 5;
  260.     {- ... or after the assembly code -}
  261.   END; {PrintScreen}
  262.  
  263.  
  264.  
  265. 4. The Internal Statement
  266.  
  267. The Internal statement is intended as a convenient mechanism for
  268. moving working External assembly code into your program, or for
  269. developing assembly code intended for final compilation with an
  270. external assembler.  (Note however that the Assemble statement
  271. provides an equally powerful mechanism for using assembly language
  272. which has fewer limitations and is considerably easier to use,
  273. allowing, for example, direct reference to procedure and function
  274. parameters by name).
  275.  
  276. First, please refer to the Version 4 Owner's Handbook or Version 5
  277. Reference Guide for the syntax for using EXTERNAL programs.  The
  278. following discussion assumes you are converting an existing EXTERNAL
  279. program to INTERNAL.
  280.  
  281. For Internal Proc/Functions defined in a PROGRAM, the following
  282. changes are required:
  283.  
  284.   1)  Remove or comment out the Link directive {$L ...}
  285.       Internal Proc/Functions are automatically linked by the Turbo
  286.       smart linker, with dead code removal on a Proc by Proc basis.
  287.  
  288.   2)  Replace the word "External" with "Forward" in the
  289.       Proc/Function heading.
  290.  
  291.   3)  The Internal statement should be placed somewhere following
  292.       the forward declaration and before the PROGRAM "BEGIN" block.
  293.  
  294. For Internal Proc/Functions defined in a UNIT, the following
  295. changes are required within the IMPLEMENTATION section:
  296.  
  297.   1)  Remove or comment out the Link directive {$L ...}
  298.       Internal Proc/Functions are automatically linked by the Turbo
  299.       smart linker, with dead code removal on a Proc by Proc basis.
  300.  
  301.   2a) For PRIVATE Proc/Functions which are defined only in the
  302.       implementation section, replace the word "External" with
  303.       "Forward" in the Proc/Function heading.
  304.  
  305.   2b) For PUBLIC Proc/Functions which are defined in the interface
  306.       section, remove or comment out the entire Proc/Function
  307.       heading in the implementation section.
  308.  
  309.   3)  The Internal statement should be placed in the implementation
  310.       section somewhere following the forward declaration (if present)
  311.       and before the Unit "BEGIN" block (if present).
  312.  
  313. Ths syntax required in the INTERFACE section of a Unit is the same
  314. as for External.
  315.  
  316. The requirements above can be summarized as follows:
  317.  - No link directive is required
  318.  - No reference should be made to "External"
  319.  - The procedure or function must be declared to the compiler
  320.      precisely once prior to the Internal statement.  If such
  321.      a declaration is not already present (eg, in the interface
  322.      section, or in a Version 5.5 Object Type definition), then 
  323.      you must provide a "forward" declaration.
  324.  
  325. The full syntax for the Internal statement is given below.
  326.  
  327. Examples:
  328.  
  329. {- The following code section implements an Internal PROC in a    -}
  330. {- PROGRAM or as a PRIVATE Proc in a Unit IMPLEMENTATION section. -}
  331.  
  332.         PROCEDURE PrintScreen; Forward;
  333.  
  334.         Internal Print
  335.         CODE Segment
  336.         PrintScreen PROC NEAR
  337.           Int 5
  338.           Ret
  339.         PrintScreen ENDP
  340.         CODE ENDS
  341.         END
  342.  
  343.         BEGIN {MAIN program or UNIT initialization}
  344.           PrintScreen;
  345.         END.
  346.  
  347. {- The following code defines a unit with a single public PROC    -}
  348. {- which is implemented using an Internal statement.              -}
  349.  
  350.         Unit PrtScr;
  351.         interface
  352.           PROCEDURE PrintScreen;
  353.  
  354.         implementation
  355.           Internal Print
  356.           CODE Segment
  357.           PrintScreen PROC FAR
  358.             Int 5
  359.             Ret
  360.           PrintScreen ENDP
  361.           CODE ENDS
  362.           END
  363.  
  364.         END. {Unit PrtScr}
  365.  
  366.  
  367.  
  368. The following syntax description is admittedly somewhat obtuse;
  369. It is intended to be read in the context of a working External
  370. procedure or function.  (Most external assembly code written for
  371. Turbo Versions 4.0 or 5.0 should already match this syntax).
  372.  
  373. The syntax for the Internal statement is:
  374.  
  375.     Internal <DataName> <remainder of line must be empty>
  376.  
  377.       Data Segment <options (ignored)>          \
  378.         <data allocation and EXTRN statements>    > optional
  379.       Data ENDS                                 /
  380.  
  381.       Code Segment <options (ignored)>
  382.         <optional assembler overhead statements (ignored)>
  383.  
  384.         <ProcName1> PROC <optional Near/Far specification>
  385.           <Standard Assembly language statements>
  386.           <MUST include at least one "RET <ParamSize>">
  387.         <ProcName1> EndP
  388.  
  389.         <additional PROC/ENDP sections>           > optional
  390.  
  391.       Code ENDS
  392.  
  393.       END <optional text (ignored)>
  394.  
  395. (Note: "DataName" must not duplicate any other Pascal identifier
  396.         used in your program).
  397.  
  398. Please Note: assembly ends with the first "End" encountered in the
  399. mnemonic field.  Everything to the right of "End" is ignored, and
  400. the next line will be treated as the start of a new Pascal
  401. statement.
  402.  
  403. It is the programmer's responsibility to insure that the assembly
  404. code matches the syntax required for external assembly code for the
  405. particular compiler version being used, with the following
  406. exception:
  407.  
  408.   All GLOBAL Pascal identifiers that have been defined prior to the
  409.   Internal statement may be referenced by name, without the need
  410.   for an EXTRN statement.  (TP&Asm ignores all EXTRN statements).
  411.   This includes references involving UnitName and record component
  412.   qualifiers, which are not permitted in EXTERNAL routines.
  413.  
  414. In particular, the programmer must insure that parameters and
  415. function results are correctly referenced relative to a properly
  416. initialized base or index register, and that parameters and/or
  417. function results are removed from the stack on exit as required by
  418. the particular compiler version being used.  Again, this should
  419. automatically be true for working external code designed for that
  420. compiler version.
  421.  
  422. Please see the file INTERNAL.PAS on the distribution disk for
  423. an example of an Internal statement which contains assembly code
  424. for both a Procedure and a Function.
  425.  
  426.  
  427. Note:
  428. Prior to Release 2 of TP&Asm each Internal PROC was implemented as
  429. a standard Pascal Procedure or Function, with additional code added
  430. as necessary to reverse the effects of the standard Procedure entry
  431. code.  Beginning with Release 2, TP&Asm builds Internal PROCs with
  432. no entry or exit code.  (In the examples above, for example, the
  433. procedure PrintScreen will consist of precisely 3 bytes of code).
  434.  
  435.  
  436.  
  437.  
  438. 5. General Assembler Syntax
  439.  
  440. This section is NOT intended to be an assembly language tutorial.
  441. It contains only a few brief notes intended to compare TP&Asm
  442. syntax requirements with the requirements of other assemblers you
  443. may own or be familiar with.
  444.  
  445. Because of its quick feedback and ability to freely mix Pascal and
  446. Assembly statements, TP&Asm is an excellent tool to use in learning
  447. Assembly language.  Please, however, plan to obtain a separate
  448. tutorial or reference on the use of 8086/88 Assembly language.
  449.  
  450. The assembler I use and recommend for stand-alone and/or linkable
  451. assembly language program/modules is A86, a full featured shareware
  452. assembler written by Eric Isaacson.  It comes complete with a very
  453. nice reference manual on disk, which, together with a few working
  454. sample programs, MAY be all you need to learn the basics of assembly
  455. language programming.
  456.  
  457.  
  458. General notes:
  459.  
  460. The basic syntax of a TP&Asm assembly statement is:
  461.  
  462. <optional label> <mnemonic> <operands> <optional comment>
  463.  
  464. These language elements can be upper or lower (or mixed) case, and
  465. may be placed in any position on the line, separated from each
  466. other by at least one space or tab.
  467.  
  468. The comment, if present, must begin with a semicolon and extends to
  469. the end of the line.  TP&Asm ignores everything following the
  470. semicolon, except as noted below under TP&Asm-specific options.
  471.  
  472. The label, if present, must not duplicate any Pascal identifier
  473. used in your program, and must be unique from other labels used in
  474. the same assemble statement, with the following exception:  For
  475. compatibility with A86, labels which consist of a single letter
  476. followed by any number of decimal digits (L1, P253, etc) are
  477. considered to be "Local labels" which may be redefined and reused.
  478. Code labels must end with a colon, except for PROC statements, in
  479. which a colon is optional.  Data labels must not end with a colon.
  480.  
  481. The mnemonic can be any standard 8086 mnemonic, optionally prefixed
  482. by one of the following:
  483.  
  484.   LOCK
  485.   A segment override: Cs, Ds, Es, or Ss
  486.   A string repeat prefix: Rep, RepZ, RepNZ, RepE, or RepNE
  487.  
  488. Use of a colon after the prefix is optional.  Prefixes may be
  489. placed on the preceding line, if desired.  It is generally an error
  490. to specify more than one prefix for the same instruction (in the
  491. sense that the processor may not do what you intended), however
  492. TP&Asm supports all combinations of one segment override with one
  493. string prefix, by converting the combination to a loop as
  494. illustrated below:
  495.  
  496.   RepE Cs Movsb       is converted to        L0: Cs Movsb
  497.                                                  LoopE L0
  498.  
  499. which moves bytes from Cs:[Si] to Es:[Di].  (If the loop technique
  500. is not used, "RepE Cs Movsb" may not repeat, and "Cs RepE Movsb"
  501. may take the first byte from Cs:[Si], and subsequent bytes from the
  502. default Ds:[Si] - probably not what you intended).  Note that the
  503. default (Es) DESTINATION segment for string operations cannot be
  504. overridden - this is a requirement of the processor, not TP&Asm.
  505.  
  506. A full list of supported mnemonics is provided below.  The file
  507. USAGE.PAS contains one or more examples of correct usage of each
  508. of the supported mnemonics.
  509.  
  510.  
  511. Operands refers to any operands required by the mnemonic, separated
  512. by commas.  Either source or destination operand may be prefixed by
  513. a segment override, where again, use of a colon is optional:
  514.  
  515.   Mov Ax,Es:[Di]
  516.  
  517. If the size of the operand (Byte, Word, or DWord) is not known to
  518. the assembler, or if you wish to use an operand differently than it
  519. was defined, you must place one of the following size specifiers
  520. before the operand (specifiers on the same line are synonyms):
  521.  
  522.     B          Byte Ptr
  523.     W          Word Ptr
  524.     D          DWord Ptr
  525.  
  526. Examples:
  527.  
  528.   Mov Ax,ByteVar   ; Syntax error if you defined VAR ByteVar: BYTE;
  529.   Mov Ax,W ByteVar ; Load Ax with two bytes beginning with ByteVar
  530.   Mov W Ax,ByteVar ; Same as above, overrides original definition
  531.  
  532.  
  533. The following conventions apply regarding numeric operands:
  534.  
  535.   As with other assemblers, all numbers must begin with a DECIMAL
  536.   digit. (Thus Ch is a register, and 0Ch is a hexidecimal number).
  537.  
  538.   For compatibility with A86, all numbers that begin with "0" are
  539.   assumed to be hexidecimal, whether or not there is a trailing
  540.   "h".  (Use Radix 10 to disable this assumption in the current
  541.   assemble/internal statement).
  542.  
  543.   For compatibility with INLINE.COM, all numbers that begin with
  544.   "$" are hexidecimal (and should NOT have a trailing "h").
  545.  
  546.   The Radix (or .Radix) statement may be used to specify the
  547.   default base for numbers which would otherwise be ambiguous,
  548.   namely, decimal digits without leading "$" or trailing "H".
  549.   Use "Radix 10" to specify decimal, "Radix 16" for hexidecimal,
  550.   and "Radix" to return to the default (leading 0 hexidecimal,
  551.   otherwise decimal).
  552.  
  553.   TP&Asm does not support binary numeric operands.  Please convert
  554.   Binary operands to Hexidecimal.
  555.  
  556.   TP&Asm supports 4-function arithmetic on immediate (constant,
  557.   NON-Data) operands, plus BIT and BY for compatability with A86.
  558.   Standard order of evaluation applies, but may be overridden
  559.   through the use of parentheses:
  560.  
  561.     Mov Al,2+3*6   ; same as Mov Al,20  (evaluate 3*6 first)
  562.     Mov Al,(2+3)*6 ; same as Mov Al,30  (evaluate 2+3 first)
  563.  
  564.  
  565. Notes on Use of Offsets and SEG DATA as numeric operands:
  566.  
  567.   Within the FIRST code block of a Program or Unit, the offset of
  568.   any assembly code or data label may be used in any instruction
  569.   which requires immediate data:
  570.  
  571.     Mov Ax,Offset AssemblyDataLabel
  572.     Sub Bx,AssemblyCodeLabel
  573.  
  574.   References to assembly Code labels refer to the OFFSET of the
  575.   labeled instruction within the current code segment.  The modifier
  576.   "Offset" is not required.  References to Data labels refer to the
  577.   CONTENTS of the labeled location unless preceded by the modifier
  578.   "Offset".
  579.  
  580.   If the first code block is a CsData statement as described in the
  581.   section TP&Asm-specific Options, the Contents or Offset of any
  582.   CsData Data label may be referenced in any subsequent Procedure
  583.   or Function, as well as in the main Program or Unit BEGIN block:
  584.  
  585.     Cmp Bx,Offset CsDataLabel
  586.  
  587.   Reference to Pascal LABEL Offsets is not permitted.
  588.  
  589.   Throughout each Program or Unit, the offset of any Pascal
  590.   Procedure, Function, or Variable may be used in any instruction
  591.   which requires immediate data, with the following exceptions:
  592.  
  593.     1) Byte references to Pascal Offsets are not permitted.  For
  594.        example, "Mov Al,Offset PascalSymbol" is not permitted even
  595.        if Ofs(PascalSymbol) is in [0..127].
  596.  
  597.     2) "Offset PascalSymbol" is not permitted as immediate data
  598.        when the Destination operand is a Pascal Variable.  For
  599.        example, "Add PascalVariable,Offset PascalSymbol" is not
  600.        permitted.  The following technique must be used:
  601.  
  602.          Mov Reg,Offset PascalSymbol
  603.          Add PascalVariable,Reg
  604.  
  605.   References to Pascal Procedure and Function identifiers refer to
  606.   the OFFSET of the Proc/Function within its code segment (except
  607.   when SETTING Function Results as described below).  The modifier
  608.   "Offset" is not required.  References to Pascal VAR and (Typed)
  609.   CONST identifiers refer to the CONTENTS of the Data Segment
  610.   location unless preceded by the modifier "Offset":
  611.  
  612.     Mov Ax,Offset PascalVariable
  613.     Dw PascalProcedure,PascalFunction
  614.  
  615.   The construct "SEG DATA" may be used in any assembly instruction
  616.   which requires immediate data, with the exceptions that Byte
  617.   references to "SEG DATA" are not permitted.  For example, to
  618.   restore the Turbo DS within a customized interrupt routine:
  619.  
  620.     Mov Ax,SEG DATA
  621.     Mov Ds,Ax
  622.  
  623.  
  624. Notes on Absolute Code Segment References:
  625.  
  626.   TP&Asm permits assembly data to be freely allocated and referenced
  627.   throughout the FIRST code block in each Program or Unit (that is,
  628.   the FIRST true Procedure or Function in a Program or Unit, or the
  629.   main BEGIN block of a Program or Unit with no Procedures or
  630.   Functions defined).  Data labels are retained in the symbol table
  631.   throughout the first code block so that all assembly sections can
  632.   reference the allocated data.  This data is considered local to
  633.   the first code block and is not available to subsequent Procedures
  634.   and Functions.
  635.  
  636.   Since Turbo Versions 4 and 5 use "smart linking", it is generally
  637.   not possible to accurately specify the location of any but the
  638.   FIRST Proc/Function in a Program or Unit.  For that reason, TP&Asm
  639.   does not permit reference to assembly Data allocated in subsequent
  640.   Procedures or Functions.  Attempts to do so will result in the
  641.   error "Invalid Absolute CSeg Reference".
  642.  
  643.   Use of assembly data definition is seldom necessary, and should
  644.   generally be avoided in favor of using Pascal data defined via
  645.   VAR or (Typed) CONST statements.
  646.  
  647.   The file DEMOTPA.PAS in the archive TP-ASM contains examples using 
  648.   data allocated in the first Procedure of a Program.
  649.  
  650.  
  651. Notes on Forward References in Data Manipulation Instructions:
  652.  
  653. TP&Asm is somewhat restrictive regarding the use of forward
  654. references in Data Transfer, Arithmetic, and Logic instructions
  655. (as opposed to Control Transfer instructions).  In particular:
  656.  
  657.   All Pascal identifiers used as operands must be defined PRIOR
  658.   TO the current Assemble or Internal statement.  (This is
  659.   consistent with the standard Pascal requirement that all
  660.   identifiers be defined).
  661.  
  662.   The Internal DATA SEGMENT section, if present, must preceed the
  663.   CODE SEGMENT section.
  664.  
  665.   FORWARD reference to assembly Data labels is not permitted.  (All
  666.   data definitions must be placed PRIOR TO the first reference).
  667.   This is not really a restriction for assembly language within a
  668.   Pascal program.  The only reason you might be tempted to have data
  669.   at the end of your assembly code is to reduce the size of the
  670.   compiled program by placing buffers and other uninitialized data
  671.   after the last Code statement.  Since your last assembly statement
  672.   can never be assumed to be the last code statement in your Pascal
  673.   program, this is simply not allowed.  Instead, define
  674.   uninitialized data in Pascal:
  675.     Var Buffer: ARRAY[1..20000] OF BYTE;
  676.  
  677.   Forward reference to CODE labels in the FIRST code block of a
  678.   Program or Unit is permitted.  For example:
  679.  
  680.     Add Ax,ForwardLabel - $
  681.  
  682.   is permitted within the FIRST true Procedure or Function in
  683.   a Program or Unit.
  684.  
  685.  
  686. Notes on Operands to Control Transfer Statements:
  687.  
  688.   Control Transfer statements include the unconditional Jmp and
  689.   Call, and the conditional Jumps (jZ, jPE, jCXZ, etc) and Loops
  690.   (Loop, LoopNE, etc).  The operand to a Direct control transfer
  691.   statement must be a SINGLE symbol name which is either:
  692.  
  693.     1) an assembly code label (including PROCs) within the current
  694.        Assemble statement (or the current major PROC of the current
  695.        Internal statement),
  696.     2) a Pascal LABEL within the current block, or
  697.     3) (for Call and Jmp only) a Pascal or Internal Procedure or
  698.        Function Identifier.
  699.  
  700.   The operand to an Indirect control transfer statement may be any
  701.   valid register or memory expression of the appropriate (Word or
  702.   DWord) size.
  703.  
  704.   Version 5.5 Virtual Method calls are indirect control transfers.
  705.   When a Virtual Method identifier is combined with an indexed
  706.   memory expression, the method identifier is interpreted as the
  707.   offset of the method within its VMT, and is added to any other
  708.   offsets specified in computing the final effective address.
  709.   Virtual Method Calls are fully described in the file TP&ASM.OOP.
  710.  
  711.   The JMP modifiers "Short" and "Long" (as used by A86) are
  712.   permitted but are ignored.  TP&Asm performs automatic minimum
  713.   Jump-Sizing for all backward AND FORWARD Jumps and Loops (Jmp,
  714.   jZ, jAE, jCXZ, Loop, LoopNZ, etc) within the current code block.
  715.   A 3-, 5-, or 7-byte instruction sequence will automatically be
  716.   generated if the target label is not within range of a 2 byte
  717.   instruction.
  718.  
  719.   This includes automatic shortening of unconditional jumps:
  720.  
  721.      Jmp CloseBy    .. becomes ..    Jmp Short CloseBy ;2 bytes
  722.  
  723.   Automatic 5 byte "IF <Cond> Jmp" for backward AND FORWARD
  724.   conditional jumps out of range:
  725.  
  726.      jNZ FarAway    .. becomes ..        jZ >L0        ;2 bytes
  727.                                          Jmp FarAway   ;3 bytes
  728.                                      L0:
  729.  
  730.   And automatic 7 byte instruction sequences for backward AND
  731.   FORWARD jCXZ & Loop's out of range:
  732.  
  733.      Loop FarAway   .. becomes ..        Loop >L0      ;2 bytes
  734.                                          Jmp Short >L1 ;2 bytes
  735.                                      L0: Jmp FarAway   ;3 bytes
  736.                                      L1:
  737.  
  738.   Note that TP&Asm does NOT pad forward jumps with NOP instructions,
  739.   but rather always builds the smallest possible instruction.
  740.  
  741.   The automatic Jump-Sizing feature is not enabled in (Assembly)
  742.   Inline Directive/MACROs.  As described in the Turbo 4.0 and 5.0
  743.   manuals, Inline Directives are intended for short sections of code
  744.   which are unlikely to exceed 127 bytes.  TP&Asm generates an error
  745.   if a conditional jump out of range is attempted in an (Assembly)
  746.   Inline Directive/MACRO.
  747.  
  748.   Pascal Proc/Functions can be called from assembly language using
  749.   direct or indirect calls:  "Call PasProc"  will generate:
  750.  
  751.     1) a NEAR Direct call if PasProc is a Procedure or Function
  752.          defined in the CURRENT Program or implementation section in
  753.          the {$F-} state.
  754.     2) a FAR Direct call if PasProc is a Procedure or Function
  755.          defined in another Unit or in the CURRENT Program or
  756.          implementation section in the {$F+} state.
  757.     3) a NEAR Indirect call if PasProc is a Word (Integer) Variable.
  758.          PasProc must be initialized with the Ofs of a NEAR {$F-}
  759.          Procedure or Function in the CURRENT Program or Unit.
  760.     4) a FAR Indirect call if PasProc is a Pointer or Procedure
  761.          Variable.  PasProc must be initialized with the Addr of a
  762.          FAR {$F+} Procedure or Function.
  763.  
  764.   The default action in (3) may be overridden using the FAR
  765.   modifier:  "Call Far PasProc"  will generate:
  766.  
  767.    3b) a FAR Indirect call if PasProc is any Pascal Variable.
  768.          MemL[DSeg:Ofs(PasProc)] must be initialized with the Addr
  769.          of a FAR {$F+} Procedure or Function.
  770.  
  771.   The default action in (4) may be overridden using the NEAR
  772.   modifier:  "Call Near PasProc"  will generate:
  773.  
  774.    4b) a NEAR Indirect call if PasProc is any Pascal Variable.
  775.          MemW[DSeg:Ofs(PasProc)] must be initialized with the Ofs of
  776.          a NEAR {$F-} Procedure or Function in the CURRENT Program
  777.          or Unit.
  778.  
  779.   The default actions in (1) and (2) may not be overridden, as
  780.   this would always result in a mismatch between the Call and Ret
  781.   instructions.
  782.  
  783.   For completeness, TP&Asm permits an unconditional JMP to a Pascal
  784.   Procedure or Function.  This would be useful only in very obscure
  785.   situations, and should otherwise be avoided.  A 3-byte Near jump
  786.   or 5 byte Far jump is built, as necessary.  The modifier "Short",
  787.   if present, is ignored, since the Turbo linker does not permit
  788.   Byte references.
  789.  
  790.  
  791. Notes on setting Function Results:
  792.  
  793.   To facilitate the setting of Pascal function results within
  794.   assembly sections, Pascal Function identifiers of any simple TYPE
  795.   can be specified as the Destination operand of a MOV instruction:
  796.  
  797.     Mov ByteFunction,Al    - OR -     Mov PointerFunction,Ax
  798.                                       Mov PointerFunction+2,Dx
  799.  
  800.   The Function identifier should be thought of as representing a
  801.   local variable of the appropriate size which is stored in the
  802.   Stack segment and accessed relative to the Bp register.  As with
  803.   all local variables, the explicit specification of the [Bp] is
  804.   not required.
  805.  
  806.   Pascal String Function identifiers can be specified as the Source
  807.   operand in a Load Pointer (Les/Lds) instruction:
  808.  
  809.     Les Di,StringFunction ; Load Pointer to temporary storage area
  810.     Es Mov [Di],Cl        ; Put in Result Length
  811.     Inc Di                ; Point past length byte
  812.     Rep MovSB             ; Put in String
  813.  
  814.   String Function identifiers refer to the local Pointer Variable
  815.   which is pushed on the stack by the Calling procedure and which
  816.   references the temporary storage location established by the
  817.   Caller.
  818.  
  819.   You should not attempt to set a Function result from within a
  820.   nested sub-procedure.
  821.  
  822.  
  823. Notes on use of Qualified Identifier Syntax:
  824.  
  825.   TP&Asm supports the full qualified identifier syntax including
  826.   both UnitName and record component qualifiers, for example:
  827.  
  828.     Test Ax,DOS.FZero
  829.     Cmp Ax,UnitX.RecVar.NestRec.IntegerComponent
  830.  
  831.   UnitName qualifiers must be defined in a "Program" or "Unit"
  832.   statement.  (The symbol "PROGRAM" is not a valid qualifier).
  833.  
  834.   Embedded spaces are not permitted, so that the following would
  835.   generate syntax errors:
  836.  
  837.     Test Ax,DOS. FZero
  838.     Cmp Ax,UnitX.RecVar. NestRec.IntegerComponent
  839.  
  840.   Following a valid UnitName qualifier, the subsequent search
  841.   is limited to PASCAL identifiers in the given unit.  Likewise,
  842.   following a valid record variable with a trailing ".", the
  843.   subsequent search is limited to record components associated
  844.   with that variable.  This duplicates the compiler's symbol
  845.   search strategy, and permits references to record components
  846.   which duplicate assembly variables and reserved symbols.
  847.   Thus, if RegVar is of TYPE Registers (from the DOS unit), the
  848.   following is permitted:
  849.  
  850.     Mov Ax,RegVar.Ax  ;- ( ">" or "<" not required )
  851.  
  852.   (If you wish to specify a record variable offset which is not
  853.   a valid component name, including Pascal and assembly constants,
  854.   use "+" in place of ".".  Thus, if PasConst = 4 and AsmSym EQU 4,
  855.   the following statements are all equivalent:
  856.  
  857.     Add Ax,RegVar.Cx
  858.     Add Ax,RegVar+AsmSym
  859.     Add Ax,RegVar+PasConst  ;
  860.  
  861.   whereas "Add Ax,RegVar.PasConst" would generate a syntax error).
  862.  
  863.   The symbolic value of a record ComponentName is the numeric
  864.   offset of that component from the beginning of the record.  To
  865.   reference this value irrespective of any record variable, you
  866.   must prefix the ComponentName with a TypeDef qualifier.  For
  867.   example,  "Add Di,DateTime.Hour"  is the same as  "Add Di,6",
  868.   because 3 Integers (and hence 6 bytes) preceed Hour within the
  869.   record type DateTime.  Use of TypeDef qualifiers permits assembly
  870.   reference to Dynamic record variables.  For example, to refer
  871.   to RecPtr^.ComponentX, where RecPtr is a VAR of TYPE ^RecType:
  872.  
  873.     Les Di,RecPtr ; Load Pointer into Es:Di
  874.     Es Mov Ax,[Di]RecType.ComponentX ; apply ComponentName offset
  875.  
  876.   Note also that within a given Assemble/Internal statement, you can
  877.   define assembly equates, permitting references like the following:
  878.  
  879.     AsmPtr EQU W Es [Di]
  880.      :
  881.     Les Di,RecPtr ; Load Pointer into Es:Di
  882.     Mov Ax,AsmPtr.RecType.ComponentX ; apply ComponentName offset
  883.  
  884.   Reference to a ComponentName without a Record Variable or Record
  885.   Type qualifier is not permitted.
  886.  
  887.   References to Version 5.5 Object components are similar to Record
  888.   component references and are fully described in the file TP&ASM.OOP.
  889.  
  890.  
  891. The following additional notes regarding operands apply:
  892.  
  893.   Pascal identifiers used as operands may optionally be prefixed
  894.   by "<" or ">".  This is primarily for compatability with Dave
  895.   Baldwin's INLINE.COM, but also serves one other purpose: it
  896.   allows you to refer to Pascal identifiers which duplicate
  897.   assembler reserved symbols.  Thus:
  898.  
  899.     Mov Al,Ch  ; Places contents of Ch register into Al
  900.     Mov Al,>Ch ; Places value of Pascal variable Ch into Al
  901.     Mov Al,Ch1 ; Ch1 is not reserved - no ">" or "<" required
  902.  
  903.   For compatability with A86, "Local labels" (described above) used
  904.   as operands may be prefixed by ">" to force a forward jmp when
  905.   there is a prior definition:
  906.  
  907.     jNE L0  ; Backward jump if already defined (otherwise forward)
  908.     jNE >L0 ; Forward jump even if there is a prior definition
  909.  
  910.   Since TP&Asm assembly code labels are required to be unique from 
  911.   all Pascal identifiers, the above two uses of '>' will always be
  912.   resolved unambiguously.
  913.  
  914.  
  915.  
  916. Notes for users of A86, by Eric Isaacson:
  917.  
  918.   Multiple operands to Push, Pop, Inc, and Dec are supported.
  919.   Segment overrides can be specified for each operand:
  920.     Push [Si],Es:[Di],[Bx] ; uses default Ds for [Si] and [Bx]
  921.   Or a single segment override can be specified for all operands:
  922.     Es Push [Bx+2],[Bx]    ; uses Es override for both operands
  923.  
  924.   The final numeric operand to Inc and Dec is not supported.
  925.     Inc Ax,3 ; will a generate syntax error
  926.     Add Ax,3 ; use this instead
  927.  
  928.   The IF statement is supported, including "IF NCXZ" (for whatever
  929.   it's worth).
  930.  
  931.   Local labels are supported, as described above.  A local label
  932.   which is never redefined does not require a ">" for forward
  933.   references.
  934.  
  935.   Conditional Returns, Extensions to MOV, Operands to AAD/AAM, and
  936.   Single-Operand TEST's are not supported.
  937.  
  938.  
  939.  
  940. Notes for users of MicroSoft's MASM:
  941.  
  942.   TP&Asm supports the basic syntax used by the MicroSoft Macro
  943.   Assembler, at least, to the best of my ability to determine that
  944.   by studying assembly programs designed for MASM.  If you discover
  945.   any incompatabilities with commonly used MASM syntax, please let
  946.   me know.
  947.  
  948.   TP&Asm supports a number of extensions for compatability with
  949.   Eric Isaacson's A86 assembler, including multiple operands to
  950.   Push, Pop, Inc, and Dec, Reusable local labels, and convenient
  951.   abbreviations for Word Ptr, Byte Ptr, etc. (described above under
  952.   General Notes).  The following compatability extension has not
  953.   yet been described:
  954.  
  955.     IF <condition> <statement>  : the single statement specified
  956.       will execute if the condition holds at runtime.  Valid
  957.       conditions are those for which there is a conditional jump
  958.       instruction for the OPPOSITE condition. ("IF NCXZ" is allowed;
  959.       "IF CXZ" is not allowed since there is no jNCXZ instruction).
  960.  
  961.     Example:
  962.                                                 jZ L1
  963.       IF NZ Mov Result,FALSE ; same as -->      Mov Result,FALSE
  964.                                               L1:
  965.  
  966.  
  967. Notes for users of INLINE.COM, by Dave Baldwin:
  968.  
  969.   As noted above, TP&Asm permits the use of "$" as a hexidecimal
  970.   specifier, and allows (but does not require) ">" or "<" to be
  971.   used as a prefix to Pascal identifiers.  These were features of
  972.   the INLINE.COM version I have seen, and may or may not be
  973.   required in the current version.
  974.  
  975.   TP&Asm does not permit the use of BY, WO, and DW as abbreviations
  976.   for Byte Ptr, Word Ptr, and DWord Ptr.  (BY and DW are reserved
  977.   by the assembler for other purposes).  Use the unabbreviated
  978.   forms, or the abbreviations B, W, and D.
  979.  
  980.   Please see the MASM user's notes for a description of the IF
  981.   statement, not described under General Notes.
  982.  
  983.  
  984.  
  985.  
  986. 6. TP&Asm-specific Options
  987.  
  988. This section describes certain features that are unique to the
  989. TP&Asm integrated assembler.
  990.  
  991.  
  992. The Pas Statement
  993.  
  994. TP&Asm provides the assembly keyword "Pas" for inserting single
  995. or multiple line Pascal statements within an assembly section.
  996. This may be used as an alternative to:
  997.   1) breaking the Assemble section into two or more blocks, and
  998.   2) defining the target of any jumps which cross the Pascal code
  999.      in a Pascal Label statement.
  1000.  
  1001. To include one or more lines of Pascal statement(s) within an
  1002. assemble statement, simply precede each line with the prefix
  1003. "Pas".
  1004.  
  1005. Pascal statements may modify any of the following registers:
  1006.    Ax, Bx, Cx, Dx, Di, Si, and Es
  1007. Your assembly code should save and restore these registers as
  1008. needed.
  1009.  
  1010. Example:
  1011.  
  1012.   Assemble
  1013.      :
  1014.     jNZ TargetLabel1
  1015.      :
  1016.     jAE TargetLabel2
  1017.      :
  1018.     Push Ax,Cx  ;preserve registers Ax and Cx
  1019.     Pas BlockRead(InFile,Buffer,SizeOf(Buffer),BytesRead);
  1020.     Pop Cx,Ax
  1021.    TargetLabel2:
  1022.      :
  1023.    TargetLabel1:
  1024.      :
  1025.   End; {Assemble}
  1026.  
  1027.  
  1028. The Pas statement may be used to implement conditional assembly as
  1029. shown in the following example:
  1030.  
  1031.   Assemble
  1032.      :
  1033.    Pas {$IFNDEF VER40}
  1034.     Call DosVersion ;This will assemble if VER40 is NOT defined
  1035.    Pas {$ELSE}
  1036.     Mov Ah,30h      ;This will assemble
  1037.     Int 21h         ; if VER40 is defined
  1038.    Pas {$ENDIF}
  1039.     Cmp Al,3
  1040.      :
  1041.   End; {Assemble}
  1042.  
  1043. Internal PROCs do not generate the standard Pascal procedure entry
  1044. code and therefore cannot safely execute Pascal statements.  For
  1045. this reason, the Pas statement is not permitted in an Internal
  1046. block.
  1047.  
  1048.  
  1049. The CsData Statement
  1050.  
  1051. Beginning with version 4, Turbo Pascal Typed Constants are no
  1052. longer stored in the Code segment.  This change was required, among
  1053. other reasons, because of the fact that Version 4 programs can have
  1054. multiple Code segments.  Nonetheless, in certain very specific
  1055. situations, it is useful to be able to place named data in the
  1056. current Code segment.  As described in the preceding section, TP&Asm
  1057. permits the allocation of Local data in the Code Segment within the
  1058. FIRST code block in any Program or Unit.
  1059.  
  1060. TP&Asm also permits the allocation of Global data in the current
  1061. Code Segment in a block beginning with the keyword "CsData".  The
  1062. CsData statement must be the FIRST Code block in the current Program
  1063. or Unit.  The syntax for the CsData statement is as follows:
  1064.  
  1065.       CsData  {remainder of line may contain a comment}
  1066.         :
  1067.        <Db, Dw, and/or Dd statements>
  1068.         :
  1069.       End;    {semicolon is required}
  1070.  
  1071. The CsData block is implemented as a "Procedure" with no executable
  1072. code, beginning at offset 0 within the current code segment.  All
  1073. references to the first data label (at offset 0) are passed to the
  1074. Turbo smart linker to insure inclusion of the entire CsData block in
  1075. the final compiled code.  Since the Turbo linker does not permit
  1076. nonzero offset references to Pascal Procedures and Functions,
  1077. references to subsequent data labels are processed directly and not
  1078. passed to the linker.  It is therefore essential that some reference
  1079. be made to the first data label if reference is made to any CsData
  1080. labels.  Simply order the data so that an unused data label is not
  1081. placed first in the CsData block, or force inclusion of the CsData
  1082. block with a statement of the form
  1083.                      "Mov Ax,FirstDataLabel"
  1084.  
  1085. The Unit DOS21_0A.PAS in the archive TP-TSR contains an example
  1086. of the CsData statement.  It is used to implement a customized
  1087. interrupt procedure which can chain to the original interrupt vector
  1088. rather than IRET to the calling program.  To permit this, the
  1089. original value of the interrupt vector must be stored in the Code
  1090. Segment so that ALL registers may be restored before issuing an
  1091. indirect "Jmp OldVector" via the stored address.  (Addresses stored
  1092. in the Data Segment are not accessible after Ds is restored).
  1093.  
  1094.  
  1095.  
  1096. TP&Asm Directives
  1097.  
  1098. TP&Asm Directives provide a mechanism for modifying the following
  1099. characteristics of the assembler:
  1100.  
  1101.     Use of Presumptions
  1102.     Treatment of Warning Errors
  1103.  
  1104. These modifications will remain in effect for the duration of the
  1105. current Assemble/Internal statement OR until reset by another
  1106. TP&Asm directive.  The combination <semicolon><sharp>, as in ";#",
  1107. is reserved by TP&Asm to indicate the beginning of a TP&Asm
  1108. directive.  The semicolon must be the first non-blank character
  1109. on the line.
  1110.  
  1111. Use of Presumptions.
  1112.  
  1113. ;#P+   Enable   Presumptions (default)
  1114. ;#P-   Disable  Presumptions
  1115.  
  1116. TP&Asm keeps track of any Segment Overrides and/or Base register
  1117. specifications necessary to reference your Pascal and Assembly
  1118. variables.  With presumptions enabled, these segment and base
  1119. specifications are automatically provided if you choose to omit them
  1120. in your data reference.  Thus you may use
  1121.  
  1122. Mov Ax,LocalVar       ; - OR -
  1123. Mov Ax,LocalVar[Bp]   ; Full Specification
  1124.  
  1125. if LocalVar is a Local Pascal variable in the current Proc/Function;
  1126.  
  1127. If CSegVar is an assembly variable in CsData block, (see above),
  1128. then you could use any of the following
  1129.  
  1130. Mov Ax,CSegVar
  1131. Mov Ax,Cs CSegVar     ; Full Specification  - OR -
  1132. Cs Mov Ax,CSegVar     ; Full Specification
  1133.  
  1134. to reference CSegVar.  In each case TP&Asm assembles the full
  1135. specification.  Using presumptions allows you to make most
  1136. references to Pascal and Assembly variables just as you do in
  1137. Pascal, without worrying about where the compiler stores these
  1138. variables.  The resulting assembly code has the form that would
  1139. be used in a straightforward ("tiny model") assembly program with
  1140. all data accessible from the Ds register.  Note that ASSUME
  1141. statements are unnecessary, and are ignored by TP&Asm.
  1142.  
  1143. The Directive ";#P-" allows you to disable presumptions in
  1144. situations where you believe the default specification is not
  1145. correct, or if you just don't feel comfortable with the idea that
  1146. the assembler is providing these specifications 'behind your back'.
  1147. When presumptions are disabled you must use the full specifications
  1148. as indicated in the examples above.
  1149.  
  1150. You should seldom find it necessary to disable presumptions,
  1151. however there are two situations that warrant closer attention.
  1152. The first applies to string operations (Movsb, Cmpsw, etc), and
  1153. the second applies to users who want to refer to Local variables
  1154. which are not in the current Proc/Function.
  1155.  
  1156. For String operations you must of course properly initialize the Es
  1157. register to the segment of the destination string.  In addition,
  1158. the assembler must determine if a segment override is necessary in
  1159. connection with the source address in the Si register.  If Si is
  1160. loaded with an Lds instruction:
  1161.  
  1162. Lds Si,MemoryReference
  1163.  
  1164. then TP&Asm will assume the Ds register is properly initialized
  1165. and will not provide a segment override.
  1166.  
  1167. If Si is loaded in one of the following fashions:
  1168.  
  1169. Lea Si,VarName         ; - OR -
  1170. Mov Si,Offset VarName
  1171.  
  1172. and Si is NOT MODIFIED before being used in a String operation, then
  1173. TP&Asm will automatically provide any necessary override.  Si is
  1174. considered to have been modified by any instruction which has Si as
  1175. DESTINATION operand, with the following exceptions:
  1176.    Test, Cmp, Inc, and Dec
  1177. (The first two do not modify their operands.  With the second two,
  1178. TP&Asm makes the reasonable assumption that the segment associated
  1179. with the Source address in Si should not change as a result of an
  1180. Increment/Decrement operation).
  1181.  
  1182. Example:
  1183.  
  1184. Xor Ch,Ch
  1185. Lea Si,LocalStringVar  ; Local Pascal VARs are stored on the Stack
  1186. Lodsb                  ; TP&Asm supplies Ss override
  1187. Mov Cl,Al
  1188. Rep Movsb              ; TP&Asm supplies Ss override and
  1189.                        ; converts double prefix to LOOP
  1190. Add Si,Bx              ; SI HAS BEEN MODIFIED
  1191.  ;- You have placed an address in Si for which it is impossible
  1192.  ;- for the assembler to Presume the proper segment
  1193.  ;- TP&Asm assumes you know what you're doing, and therefore
  1194.  ;- SUPPLIES NO OVERRIDE (Source will use the default Ds register),
  1195.  ;- but generates a Warning Error IF WARNINGS ARE ENABLED
  1196. Cmpsb                  ; TP&Asm supplies no override
  1197.  
  1198.  
  1199. You may determine if the assembler is providing a segment override
  1200. using ASMWATCH with Turbo 5.0.  The watch expression "CPU.CsIp^,m"
  1201. displays a hex dump beginning at current instruction.  If the first
  1202. byte of a repeated or non-repeated string instruction is $36 or $2E,
  1203. an override is being provided.
  1204.  
  1205.  
  1206. To reiterate, with respect to string operations with
  1207. Presumptions Enabled:
  1208.  
  1209.  1)  you must properly initialize the Es and Di Registers
  1210.  2a) Load Ds and Si using Lds:
  1211.      Lds Si,MemoryReference
  1212.  - OR -
  1213.  2b) Load Si only, using one of the following:
  1214.      Lea Si,VarName         ; - OR -
  1215.      Mov Si,Offset VarName
  1216.  3)  Subsequent statements SHOULD NOT MODIFY Si, until
  1217.      AFTER the string operation
  1218.  4)  you must restore Ds if it was modified
  1219.  
  1220. Or, with Presumptions Disabled:
  1221.  
  1222.  1)  you must properly initialize Es, Di, and Si
  1223.  2)  If the source string is not in the Data Segment, you must
  1224.      either set Ds to the segment of the Source string, or use
  1225.      an explicit segment override with the string mnemonic
  1226.  3)  you must restore Ds if it was modified
  1227.  
  1228.  
  1229. To reference LOCAL variables which are NOT in the current Procedure
  1230. or Function, the preferred method is to define a local variable in
  1231. the current Proc/Function and use Pascal as follows:
  1232.  
  1233. PROCEDURE Outer;
  1234. VAR SomewhatLocalVar;
  1235.  
  1236.   PROCEDURE Inner;
  1237.   VAR LocalVar;
  1238.   BEGIN
  1239.   {- if assembly code USES the value of SomewhatLocalVar: -}
  1240.     LocalVar := SomewhatLocalVar;
  1241.     Assemble
  1242.      < use LocalVar in place of SomewhatLocalVar >
  1243.     End; {Assemble}
  1244.   {- if assembly code needs to MODIFY SomewhatLocalVar: -}
  1245.     SomewhatLocalVar := LocalVar;
  1246. <etc>
  1247.  
  1248. With Turbo Versions 4 & 5 it is possible to make assembly references
  1249. to Local variables which are NOT in the current Proc/Function,
  1250. however: you will need to disable presumptions, properly initialize
  1251. the Bx register, and provide the full specification:
  1252.  
  1253. ;#P-
  1254. Mov  Bx,[Bp+4]  ; Initialize Bx to Caller's Stack Frame
  1255. Ss Mov Ax,SomewhatLocalVar[Bx]
  1256. ;#P+
  1257.  
  1258.  
  1259. Treatment of Warning Errors.
  1260.  
  1261. ;#W+   Halt on  Warnings
  1262. ;#W-   Ignore   Warnings     (default)
  1263.  
  1264. TP&Asm performs an extensive set of syntax checks on your assembly
  1265. code (including many that can only be detected at compile time), and
  1266. reports any such error on the standard compiler error line, with the
  1267. cursor placed on the line that caused the error.  The full list of
  1268. standard error messages is provided in the file TP&ASM2.REF.
  1269.  
  1270. In addition to these standard error messages there is a small set of
  1271. warning error messages, mostly having to do with possible errors in
  1272. the use of segment overrides, that will be generated only when
  1273. Warnings are enabled.  Warnings are normally disabled so as not to
  1274. interfere with (possibly) valid instructions.  Use the directive
  1275. ";#w+" to enable warnings and ";#w-" to disable them again.
  1276.  
  1277. The warning error messages are also listed, with brief explanations,
  1278. in the file TP&ASM2.REF.
  1279.  
  1280.  
  1281.  
  1282.  
  1283. 7. Supported Mnemonics
  1284.  
  1285. TP&Asm supports the following 8086 mnemonics and data definition
  1286. directives:
  1287.  
  1288.  AAA         AAD         AAM         AAS         ADC         ADD
  1289.  AND         CALL        CBW         CLC         CLD         CLI
  1290.  CMC         CMP         CMPSB       CMPSW       CWD         DAA
  1291.  DAS         DB          DD          DEC         DIV         DW
  1292.  EQU         HLT         IDIV        IMUL        IN          INC
  1293.  INT         INTO        IRET        JA          JAE         JB
  1294.  JBE         JC          JCXZ        JE          JG          JGE
  1295.  JL          JLE         JMP         JNA         JNAE        JNB
  1296.  JNBE        JNC         JNE         JNG         JNGE        JNL
  1297.  JNLE        JNO         JNP         JNS         JNZ         JO
  1298.  JP          JPE         JPO         JS          JZ          LAHF
  1299.  LDS         LEA         LES         LOCK        LODSB       LODSW
  1300.  LOOP        LOOPE       LOOPNE      LOOPNZ      LOOPZ       MOV
  1301.  MOVSB       MOVSW       MUL         NEG         NOP         NOT
  1302.  OR          OUT         POP         POPF        PUSH        PUSHF
  1303.  RCL         RCR         REP         REPE        REPNE       REPNZ
  1304.  REPZ        RET         RETF        ROL         ROR         SAHF
  1305.  SAL         SAR         SBB         SCASB       SCASW       SHL
  1306.  SHR         STC         STD         STI         STOSB       STOSW
  1307.  SUB         TEST        WAIT        XCHG        XLAT        XLATB
  1308.  XOR
  1309.  
  1310.  
  1311. The following conditional execution prefix is supported for
  1312. compatibility with Eric Isaacson's A86 assembler:
  1313.  
  1314.  IF
  1315.  
  1316.  
  1317. The following prefix is supported for inserting single or
  1318. multiple line Pascal statements within an assembly section.
  1319.  
  1320.  PAS
  1321.  
  1322.  
  1323. The following data definition and type qualifiers are supported:
  1324.  
  1325.  B           BYTE        W           WORD        D           DWORD
  1326.  BIT         BY          DUP         OFFSET      SEG DATA
  1327.  PROC        NEAR        F           FAR         ENDP
  1328.  
  1329.  
  1330. TP&Asm recognizes the following other assembly directives:
  1331.  
  1332.  ORG         RADIX       SEGMENT     ENDS        END
  1333.  
  1334.  
  1335. TP&Asm uses the standard set of register mnemonics:
  1336.  
  1337.  AL      BL      CL      DL      AH      BH      CH      DH
  1338.  AX      BX      CX      DX      SI      DI      BP      SP
  1339.  CS      DS      ES      SS
  1340.  
  1341.  
  1342. The following directives are unnecessary and are ignored:
  1343.  
  1344.  AT          COMMON      LABEL       MEMORY      PARA        STACK
  1345.  ASSUME      EXTRN       PAGE        PUBLIC      SUBTTL      TITLE
  1346.  PTR         SHORT       LONG
  1347.  
  1348. The following invalid string mnemonics should be replaced by the
  1349. five character versions specifying byte or word (CMPSB, MOVSW, etc):
  1350.  
  1351.  CMPS        LODS        MOVS        SCAS        STOS
  1352.  
  1353.  
  1354. TP&Asm does not currently support 8087 mnemonics or mnemonics
  1355. which are unique to a specific processor (80286, 80386, NEC, etc).
  1356. These mnemonics are reserved for upward compatibility to future
  1357. versions of TP&Asm, and cannot be used as Assembly data labels.
  1358.  
  1359. For compatibility with MASM, most assembly reserved words other than
  1360. prefixes and qualifiers can be used as code labels.
  1361.  
  1362. All reserved words can be used as Pascal symbols and referenced in
  1363. assembly language by prefixing the symbol with ">" or "<", or with
  1364. a valid UnitName or record qualifier, as discussed in the section
  1365. on General Assembler Syntax.
  1366.  
  1367.