Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Turbo Pascal - <b> inline inline assembler code pp 211</b> http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 INLINE                     Inline Assembler Code                     pp 211

 Syntax:  Inline (Code Elements) ;

 Type:    N/A

 Form:    Procedure or Function

 Purpose: Insert machine language code into the instruction stream.

 Notes:   An inline statement consists of the word Inline followed by one
          or more code elements separated by slashes and enclosed in
          parentheses.  Code elements are constructed of data elements.

          A data element is either an integer constant, a variable, function,
          or procedure identifier, or a location counter reference.
          The value assigned to these is that of their offset in memory, or
          for the location counter, its current value.

          A code element is built from one or more data elements and
          separated by plus (+) or minus (-) signs.
          A code element generates a byte or word of code.  The value of the
          code is calculated by adding or subtracting the values of the
          data elements according to the signs that separate them.

          Constants exist in the code segment.
          Global variables exist in the data segment.
          Local variables and procedure parameters exist on the stack.


 Example: Inline (10 / $2345 / Count+1 / (Sort-*) + 2) ;


          A code element will generate one byte of code if it consists of
          integer constants only, and if its value is within the 8 bit
          range of 0..$FF.  If the value is outside this range or if the
          code element refers to a variable, procedure, function, or location
          counter then a word of code is generated.

          The < and > characters may be used to overrid the automatic
          size selection described above.  If a code element starts with a <
          character, only the least significant byte of the value is coded.
          If an element starts with > then a word value is always coded.

 Example: Inline (<$1234/>$44) ;  results in $34, $44, $00


          Global variables are accessible via the DS register, whereas local
          variables such as those declared locally in a sub program are
          relative via the BP register in the stack segment.
          Typed constants, functions, and procedures are all relative to
          the code segment CS register.

          Inline should not attempt to access variables not within the
          current scope.  Global variables and those declared within the
          current subprogram are the current scope.  Other local variables
          only exist on the stack during the time that their parent sub
          program has control.

          Inline statements may be freely mixed throughout the statement
          part of the block, and may use all CPU registers.

          BP,SP,DS,SS registers must be the same on exit as at entry.


 Stack:   VAR parameters are passed as Offset:Segment addresses.
          Parameters are pushed on the stack from left to right.  The
          last parm will be at the lowest stack address.

             Procedure Test (VAR parm1, parm2, parm3 : Integer) ;

          Stack image at entry to INLINE code after PUSH BP:

             [BP + 08h]            ; Offset  of last parm (parm3 here)
             [BP + 0Ah]            ; Segment of last parm (parm3 here)
             [BP + 0Ch]            ; Offset  of parm2
             [BP + 0Eh]            ; Segment of parm2
             [BP + 10h]            ; Offset  of parm1
             [BP + 12h]            ; Segment of parm1

             Push  BP              ; Must save BP entry value
             Mov   BP,SP           ; Set BP to address the stack
             Mov   AX,[BP + 08h]   ; Offset  of parm3 (or last parm)
             Mov   DS,[BP + 0Ah]   ; Segment of parm3 (or last parm)
             Lds   AX,[BP + 08h]   ; Load DS,AX with parm3 segment:offset
             Lds   BX,[BP + 0Ch]   ; Load DS,BX with parm2 segment:offset
             Lds   CX,[BP + 10h]   ; Load DS,CX with parm1 segment:offset



          VALUE parameters are passed in their entirety except for
          arrays and records, which as passed as Offset:Segment addresses.

             2 bytes - Integers, Booleans, Chars
                       Byte values have zero in the most significant byte.

             4 bytes - Pointers, Arrays, Records
                       Passed as Offset:Segment double word

             6 bytes - Reals

             x bytes - Strings - first byte is string length and the
                       remaining byte(s) are the string data.

            32 bytes - Sets



 Usage:

          This example converts a string to upper case

       VAR
          Str : String [255] ;     { String to convert to upper case }

       BEGIN
          Inline
          (
          $C4 / $BE / Str /        {      Les DI,Str[BP]            }
          $26 / $8A / $0D /        {      Mov CL,ES:[DI]            }
          $FE / $C1 /              {      Inc CL                    }
          $FE / $C9 /              { L1:  Dec CL                    }
          $74 / $13 /              {      Jz  L2                    }
          $47 /                    {      Inc DI                    }
          $26 / $80 / $3D / $61 /  {      Cmp ES:Byte Ptr [DI],'a'  }
          $72 / $F5 /              {      Jb  L1                    }
          $26 / $80 / $3D / $7A /  {      Cmp ES:Byte Ptr [DI],'z'  }
          $77 / $EF /              {      Ja  L1                    }
          $26 / $80 / $2D / $20 /  {      Sub ES:Byte Ptr [DI],20h  }
          $EB / $E9                {      Jmp Short L1              }
          ) ;                      { L2:  Ret                       }
       END.




 Usage:

          This example disables the Control Break Interrupt 23h

       CONST
          Int23  :  String [5] = 'xxxxx' ;
                                   {  Value is not important
                                      [0] - string length
                                      [1] - CS saved value (2 bytes)
                                      [3] - IP saved value (2 bytes)
                                      [5] - IRET value,$CF (1 byte )
                                    }
       TYPE
          Str05  =  String [5];     { Declare type for var paramter }

       Procedure Set_Int23 (var parm1 : Str05);
          Begin
          Inline
          (                        { Must save BP entry value       }
          $55 /                    {      Push    BP                }
          $8B / $EC /              {      Mov     BP,SP             }
          $1E /                    {      Push    DS                }
          $06 /                    {      Push    ES                }
                                   { Get current Int 23h CS:IP      }
          $B4 / $35 /              {      Mov     AH,35h            }
          $B0 / $23 /              {      Mov     AL,23h            }
          $CD / $21 /              {      Int     21h               }
                                   { Get string address off stack   }
          $C5 / $76 / $08 /        {      Lds     SI,[BP + 8]       }
                                   { Save old CS:IP in string CONST }
          $8C / $44 / $01 /        {      Mov     [SI+1],ES         }
          $89 / $5C / $03 /        {      Mov     [SI+3],BX         }
                                   { Set new Int 23h vector         }
          $B4 / $25 /              {      Mov     AH,25h            }
          $B0 / $23 /              {      Mov     AL,23h            }
          $8B / $D6 /              {      Mov     DX,SI             }
          $83 / $C2 / $05 /        {      Add     DX,5              }
                                   { Create IRET code in string     }
          $C6 / $44 / $05 / $CF /  {      Mov     [SI+5],0CFh       }
          $CD / $21 /              {      Int     21h               }

          $07 /                    {      Pop     ES                }
          $1F /                    {      Pop     DS                }
                                   { Must restore BP entry value    }
          $5D                      {      Pop     BP                }
          );
          End;


       BEGIN
          Set_Int23   (Int23);     { Redirect Ctrl Break to IRET    }
       END.

See Also: External Function Intr MsDos Procedure

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson