home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / PASCAL / PASTUT34 / INLINE.TXT < prev    next >
Text File  |  1993-06-12  |  8KB  |  187 lines

  1.                      IN-LINE CODE.
  2.                      ▀▀▀▀▀▀▀▀▀▀▀▀▀
  3.  
  4. When a Turbo Pascal program is compiled it is converted to machine 
  5. code, which can be inspected using the DOS Debug utility, as 
  6. described in the module entitled 'Using Registers'. Of course, machine
  7. code can also be created by assembling code written in assembly
  8. language. This will generally be more efficient and/or precise than
  9. compiled code. 
  10.  
  11. There are two ways to link machine code with Turbo Pascal programs:
  12.  
  13. For long machine code programs, it is advisable to write these as 
  14. procedures or functions in assembly language and assemble them into 
  15. .OBJ files. They can then be called from a Turbo Pascal program 
  16. provided the procedure or function is declared as 'external'. Further 
  17. details can be found in the Reference Guide on pages 199-205. Ideally
  18. Turbo Assembler (TASM) should be used for this purpose and this lies
  19. outside the scope of these notes.
  20.  
  21. For very short assembly language subroutines, Turbo Pascal's 'inline'
  22. statements and directives are very convenient. They allow the insertion
  23. of machine code instructions directly into the program or unit instead
  24. of through an object file.
  25.  
  26. An inline statement consists of the reserved word 'inline' followed by
  27. one or more inline elements, separated by slashes and enclosed in 
  28. parentheses. The inline elements generally consist of two hexadecimal
  29. digits representing machine code operations or operands, separated 
  30. by forward slashes. The op-code for 'No OPeration' (NOP) is $90 
  31. and three such NOP codes are often used to mark compiled code for 
  32. ease of inspection. The appropriate inline statement is
  33.  
  34.      Inline($90/$90/$90);
  35.  
  36. The hexadecimal values in the inline statement are the direct 
  37. translation of assembly language mnemonics into machine code, which 
  38. can be obtained by use of the DOS Debug utility. Assembly language
  39. is a low-level language closest to the native machine code of the 
  40. computer, with each assembly language statement translating into one
  41. machine code instruction. In contrast Turbo Pascal statements may 
  42. require many machine code instructions.
  43.  
  44. Whereas it is possible to write directly in machine code, it is much
  45. easier to write in assembler, because the mnemonics used are meaningful.
  46. The 8086 instruction set has over 150 mnemonics and a suitable 
  47. reference must be consulted for full details. ('Assembly Language 
  48. Interfacing in Turbo Pascal' by Sanjiva Nath, MIS Press or 'Programming
  49. the 8086/8088' by James W. Coffron, Sybex Inc.).
  50.  
  51. A few typical assembler mnemonics are as follows:
  52.  
  53.   ADD        Add destination to source
  54.   CMP        Compare destination to source
  55.   INT        Call interrupt
  56.   IRET       Interrupt return
  57.   JMP        Jump to target
  58.   JNZ        Jump if not zero
  59.   JZ         Jump if zero
  60.   MOV        Move to destination from source
  61.   MUL        Multiply
  62.  
  63.  
  64. The mnemonic, which translates to the Op Code, is usually followed by
  65. operand(s), frequently the registers of the CPU or numerical values.
  66. This is illustrated below for a simple routine to activate the bell
  67. (ASCII code 7 or Ctrl G).
  68.  
  69.   MOV DL,07     { Move the value 7 into the register DL }
  70.   MOV AH,02     { Move the value 2 into the register AH }
  71.   INT 21        { Call interrupt 21 with AH = 2 to display output }
  72.   INT 20        { Terminate the program }
  73.  
  74. These instructions can be assembled in debug as follows:
  75.  
  76. C:>debug            { type debug after DOS prompt for active drive, etc }
  77. -a 0100             { type a and offset address after debug prompt - }
  78. 5D84:0100 mov DL,07 {                                                }
  79. 5D84:0102 mov AH,02 { type assembly language instructions            }
  80. 5D84:0104 int 21    {                                                }
  81. 5D84:0106 int 20    {                                                }
  82. 5D84:0108 [Enter]   { just press the Enter key in response to prompt }
  83. -r cx               { to ascertain the value in register CX }
  84. CX 0000             { CX contains zero at present }
  85. :08                 { enter size of routine as 8 bytes }                                                                            
  86. -n bell.com         { name the file as bell.com }                                                            
  87. -w                  { write the file to disk }                                                            
  88. Writing 0008 bytes                                                              
  89. -g                  { g(o) runs the program and sounds the bell }                                                                                                                                                              
  90. Program terminated normally 
  91.  
  92. It is now possible to unassemble the program to see the machine code
  93.                                                     
  94. -u                                                                              
  95. 5D84:0100 B207          MOV     DL,07                                           
  96. 5D84:0102 B402          MOV     AH,02                                           
  97. 5D84:0104 CD21          INT     21                                              
  98. 5D84:0106 CD20          INT     20                                              
  99. 5D84:0108 0000          ADD     [BX+SI],AL                                      
  100.  
  101. It can be seen that the op code for move immediate (07) to register DL
  102. is B2 and that move immediate (02) to the register AH is B4. The code 
  103. for calling an interrupt is CD, followed by the interrupt number.
  104.  
  105. An assembly language statement may translate into one or more bytes.
  106. Some examples are:
  107.  
  108.    90                    NOP
  109.    89E5                  MOV   BP,SP
  110.    BF5601                MOV   DI,0156
  111.    F72E3E00              IMUL  WORD PTR [003E]
  112.    C7063E000300          MOV   WORD PTR [003E],0003
  113.  
  114. Note that the offset address values and immediate values appear with the
  115. low byte first and then the high byte. The last statement involves
  116. 6 bytes, which is the maximum size.
  117.  
  118.  
  119. The bell-ring routine can now be inserted into a Turbo Pascal program
  120. to indicate a possible error, limit or reminder, as in the following 
  121. example:
  122.  
  123. program inline_example;
  124.  
  125. {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
  126. {    This program illustrates the use of Inline Machine Code.       }
  127. {                                                                   }
  128. {    The inline code causes the bell to sound to draw attention     }
  129. {                                                                   }
  130. {    to the need for further user input, after a table of results.  }
  131. {                                                                   }
  132. {    R. Shaw.        23.3.90                                        }
  133. {___________________________________________________________________}
  134.  
  135. uses Crt;
  136.  
  137. var
  138.   i,x,y         : integer;
  139.   reply         : char;
  140.  
  141. begin
  142.  repeat
  143.    ClrScr;
  144.    Writeln('PROGRAM TO MULTIPLY INTEGER NUMBERS BY 1 TO 10');
  145.    WRITELN;
  146.    write('Enter an integer number  ');
  147.    readln(x);
  148.    writeln;
  149.    writeln;
  150.    for i := 1 to 10 do
  151.      begin
  152.         y := i * x;
  153.         writeln(i:2,' * ',x:2,' = ',y:2)
  154.      end;
  155.    inline($B2/$07/$B4/$02/$CD/$21);
  156.    writeln;
  157.    writeln;
  158.    write('Do you wish to continue (y/n)? ');
  159.    readln(reply);
  160.  until UpCase(reply) <> 'Y';
  161. end.
  162.  
  163.  
  164. When using machine code it is possible to use variable names, provided
  165. that they have been predeclared, since the variable is really just an 
  166. offset value to the data in the data segment. The variable declaration
  167. in Turbo Pascal is the normal 'var' declaration. An example is given on
  168. page 205 of the Turbo Pascal reference Guide:
  169.  
  170.    inline(10/$2345/Count+1/Data-Offset);
  171.  
  172. As shown it is possible to use offset specifiers consisting of the +
  173. or - sign followed by a constant. It is also possible to use optional 
  174. size specifiers, < or >. If an inline element starts with a < operator,
  175. only the least-significant byte of the value is coded, even if it is
  176. a 16-bit value. With >, a word is always encoded, even though the 
  177. most-significant byte is 0.
  178.  
  179. In assembly language the declaration is achieved by means of the 
  180. EQU (equate) pseudo-instruction, as illustrated on page 201 of the 
  181. Reference Guide. Constant values can also be declared in this way.
  182.  
  183.  
  184. INLINE.TXT
  185. 23.3.90
  186.  
  187.