                     IN-LINE CODE.
                     

When a Turbo Pascal program is compiled it is converted to machine 
code, which can be inspected using the DOS Debug utility, as 
described in the module entitled 'Using Registers'. Of course, machine
code can also be created by assembling code written in assembly
language. This will generally be more efficient and/or precise than
compiled code. 

There are two ways to link machine code with Turbo Pascal programs:

For long machine code programs, it is advisable to write these as 
procedures or functions in assembly language and assemble them into 
.OBJ files. They can then be called from a Turbo Pascal program 
provided the procedure or function is declared as 'external'. Further 
details can be found in the Reference Guide on pages 199-205. Ideally
Turbo Assembler (TASM) should be used for this purpose and this lies
outside the scope of these notes.

For very short assembly language subroutines, Turbo Pascal's 'inline'
statements and directives are very convenient. They allow the insertion
of machine code instructions directly into the program or unit instead
of through an object file.

An inline statement consists of the reserved word 'inline' followed by
one or more inline elements, separated by slashes and enclosed in 
parentheses. The inline elements generally consist of two hexadecimal
digits representing machine code operations or operands, separated 
by forward slashes. The op-code for 'No OPeration' (NOP) is $90 
and three such NOP codes are often used to mark compiled code for 
ease of inspection. The appropriate inline statement is

     Inline($90/$90/$90);

The hexadecimal values in the inline statement are the direct 
translation of assembly language mnemonics into machine code, which 
can be obtained by use of the DOS Debug utility. Assembly language
is a low-level language closest to the native machine code of the 
computer, with each assembly language statement translating into one
machine code instruction. In contrast Turbo Pascal statements may 
require many machine code instructions.

Whereas it is possible to write directly in machine code, it is much
easier to write in assembler, because the mnemonics used are meaningful.
The 8086 instruction set has over 150 mnemonics and a suitable 
reference must be consulted for full details. ('Assembly Language 
Interfacing in Turbo Pascal' by Sanjiva Nath, MIS Press or 'Programming
the 8086/8088' by James W. Coffron, Sybex Inc.).

A few typical assembler mnemonics are as follows:

  ADD        Add destination to source
  CMP        Compare destination to source
  INT        Call interrupt
  IRET       Interrupt return
  JMP        Jump to target
  JNZ        Jump if not zero
  JZ         Jump if zero
  MOV        Move to destination from source
  MUL        Multiply


The mnemonic, which translates to the Op Code, is usually followed by
operand(s), frequently the registers of the CPU or numerical values.
This is illustrated below for a simple routine to activate the bell
(ASCII code 7 or Ctrl G).

  MOV DL,07     { Move the value 7 into the register DL }
  MOV AH,02     { Move the value 2 into the register AH }
  INT 21        { Call interrupt 21 with AH = 2 to display output }
  INT 20        { Terminate the program }

These instructions can be assembled in debug as follows:

C:>debug            { type debug after DOS prompt for active drive, etc }
-a 0100             { type a and offset address after debug prompt - }
5D84:0100 mov DL,07 {                                                }
5D84:0102 mov AH,02 { type assembly language instructions            }
5D84:0104 int 21    {                                                }
5D84:0106 int 20    {                                                }
5D84:0108 [Enter]   { just press the Enter key in response to prompt }
-r cx               { to ascertain the value in register CX }
CX 0000             { CX contains zero at present }
:08                 { enter size of routine as 8 bytes }                                                                            
-n bell.com         { name the file as bell.com }                                                            
-w                  { write the file to disk }                                                            
Writing 0008 bytes                                                              
-g                  { g(o) runs the program and sounds the bell }                                                                                                                                                              
Program terminated normally 

It is now possible to unassemble the program to see the machine code
                                                    
-u                                                                              
5D84:0100 B207          MOV     DL,07                                           
5D84:0102 B402          MOV     AH,02                                           
5D84:0104 CD21          INT     21                                              
5D84:0106 CD20          INT     20                                              
5D84:0108 0000          ADD     [BX+SI],AL                                      

It can be seen that the op code for move immediate (07) to register DL
is B2 and that move immediate (02) to the register AH is B4. The code 
for calling an interrupt is CD, followed by the interrupt number.

An assembly language statement may translate into one or more bytes.
Some examples are:

   90                    NOP
   89E5                  MOV   BP,SP
   BF5601                MOV   DI,0156
   F72E3E00              IMUL  WORD PTR [003E]
   C7063E000300          MOV   WORD PTR [003E],0003

Note that the offset address values and immediate values appear with the
low byte first and then the high byte. The last statement involves
6 bytes, which is the maximum size.


The bell-ring routine can now be inserted into a Turbo Pascal program
to indicate a possible error, limit or reminder, as in the following 
example:

program inline_example;

{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
{    This program illustrates the use of Inline Machine Code.       }
{                                                                   }
{    The inline code causes the bell to sound to draw attention     }
{                                                                   }
{    to the need for further user input, after a table of results.  }
{                                                                   }
{    R. Shaw.        23.3.90                                        }
{___________________________________________________________________}

uses Crt;

var
  i,x,y         : integer;
  reply         : char;

begin
 repeat
   ClrScr;
   Writeln('PROGRAM TO MULTIPLY INTEGER NUMBERS BY 1 TO 10');
   WRITELN;
   write('Enter an integer number  ');
   readln(x);
   writeln;
   writeln;
   for i := 1 to 10 do
     begin
        y := i * x;
        writeln(i:2,' * ',x:2,' = ',y:2)
     end;
   inline($B2/$07/$B4/$02/$CD/$21);
   writeln;
   writeln;
   write('Do you wish to continue (y/n)? ');
   readln(reply);
 until UpCase(reply) <> 'Y';
end.


When using machine code it is possible to use variable names, provided
that they have been predeclared, since the variable is really just an 
offset value to the data in the data segment. The variable declaration
in Turbo Pascal is the normal 'var' declaration. An example is given on
page 205 of the Turbo Pascal reference Guide:

   inline(10/$2345/Count+1/Data-Offset);

As shown it is possible to use offset specifiers consisting of the +
or - sign followed by a constant. It is also possible to use optional 
size specifiers, < or >. If an inline element starts with a < operator,
only the least-significant byte of the value is coded, even if it is
a 16-bit value. With >, a word is always encoded, even though the 
most-significant byte is 0.

In assembly language the declaration is achieved by means of the 
EQU (equate) pseudo-instruction, as illustrated on page 201 of the 
Reference Guide. Constant values can also be declared in this way.


INLINE.TXT
23.3.90

