*/
Do you receive the Programmer's Heaven newsletter? If not, why not subscribe?
*/

View \INTERNAL.PAS

TP&Asm Integrated Compile-Time Assembler Version 2.2

Submitted By: WEBMASTER
Rating: (Not rated) (Rate It)


{??????????????????????????? INTERNAL.PAS ???????????????????????????}
{ Demonstrates the use of an Internal statement in a Program.        }
{                                                                    }
{ Internal and External statements require that you code an entire   }
{ Procedure or Function in assembly, and that you explicitly code    }
{ any necessary entry and exit code.  For that reason it is usually  }
{ more convenient to use Assemble or Asm statements, which can be    }
{ mixed with Pascal statements on a line by line basis.  On the      }
{ other hand, Internal and External are useful when you want to      }
{ completely eliminate the standard Pascal entry and exit code.  In  }
{ the Concat example below, the compiler would normally reserve 256  }
{ bytes on the stack and make a local copy of the String Value       }
{ parameter S2.  Since this parameter will not be modified, there is }
{ no reason to reserve limited stack space and make the local copy.  }
{ Using Internal eliminates this unwanted entry code.                }
{??????????????????????????? INTERNAL.PAS ???????????????????????????}

{  No Link directive - Internal Procedures and Functions are linked  }
{  on a Proc by Proc basis by the Turbo Smart-Linker, resulting in   }
{  a smaller EXE file.  (External code is linked "all or nothing").  }

VAR
  HexDigits: ARRAY[0..15] OF CHAR;
  Str1:      String;


FUNCTION  HexByte(SourceByte: BYTE): INTEGER;         Forward;
PROCEDURE Concat(Var S1; S2: String; Size1: INTEGER); Forward;
{- In a PROGRAM, Use FORWARD in place of EXTERNAL -}


Internal Example;

DATA    SEGMENT WORD PUBLIC

        EXTRN   HexDigits:BYTE      ;Not required by INTERNAL

DATA    ENDS

CODE    SEGMENT BYTE PUBLIC

        ASSUME  CS:CODE,DS:DATA     ;Not required by INTERNAL

        PUBLIC  HexByte,Concat      ;Not required by INTERNAL

; FUNCTION  HexByte(SourceByte: BYTE): INTEGER; Forward;

HexByte         PROC    NEAR

        MOV     BX,SP
        MOV     AL,SS:[BX+2] ; Get parameter

        Xor     Ah,Ah        ; set Ah = 0 to prevent Divide Overflow
        Mov     Bl,010
        Div     Bl           ; Al = Quo, Ah = Rem
        Mov     Bx,Offset HexDigits
        Xchg    Al,Ah
        XlatB
        Xchg    Al,Ah
        XlatB                ; Leave result in Ax
        Ret     2

HexByte         ENDP



; PROCEDURE Concat(Var S1; S2: String; Size1: INTEGER); Forward;

; Note: the String Value parameter S2 will Not be copied into a
; local work area.  It will frequently represent a String Constant
; stored in the Code Segment in a space much smaller than 256 bytes.
; Because of this, and because of the compiler's automatic merging
; of string constants, it should not be modified.

String1         EQU     DWORD PTR [BP+10]
String2         EQU     DWORD PTR [BP+6]
SizeOf1         EQU     WORD PTR [BP+4]

Concat          PROC NEAR

        Push    Bp
        Mov     Bp,Sp
        Push    Ds
        Cld                  ;set forward
        Xor     Ax,Ax
        Mov     Cx,SizeOf1
        Dec     Cx           ;Max length is Allocated size - 1
        Xor     Ch,Ch        ;In no case let str1 exceed 255
        Les     Di,String1
        Lds     Si,String2
        Lodsb                ;length(S2)
        Add     Al,Es:[Di]   ;+Length(S1)
        jC      L1           ;exceeds 255, use Limit
        Cmp     Al,Cl
        jA      L1           ;exceeds Limit (use Limit)
        Mov     Cl,Al        ;else use sum of lengths
        Jmp     Short L2
L1:     Mov     Al,Cl
L2:     Sub     Cl,Es:[Di]   ;New length - old length(S1)
        jBE     Done         ;New < Old, don'
t shorten
        Xchg    Al,Es:[Di]   ;Put in new length, get old
        Inc     Di           ;skip length byte
        Add     Di,Ax        ;and original string to set dest
        Rep     Movsb        ;Concatenate
Done:   Pop     Ds
        Pop     Bp
        Ret     10

Concat          ENDP

CODE    ENDS

        END (Internal Example)


CONST Result: RECORD
        Len: BYTE;
        Wrd: INTEGER;
      END = (Len:2;Wrd:0);
VAR
  n: BYTE;
  ResultString: STRING[2] Absolute Result;

BEGIN {Main Program}

{- Demonstrate HexByte -}
  HexDigits:= '0123456789ABCDEF';
  FOR n := 0 TO 255 DO BEGIN
    WRITE(n:3,' ');
    Result.Wrd := HexByte(n);
    WRITE(ResultString,'  ');
  END; {FOR n := 0 TO 255 DO }
  WRITELN;

{- Demonstrate Concat -}
  Str1 := 'String1';
  WRITELN('Before Concat:  ',Str1);
  FOR n := 1 TO 5 DO BEGIN
    Concat(Str1,'String2',SizeOf(Str1));
    WRITELN('After Concat',n,':  ',Str1);
  END; {FOR n := 1 TO 5 DO }
  Concat(Str1,'XXXXXXXXXXXX',45);
  WRITELN('Partial Concat: ',Str1);

  WRITELN(#13#10'Press a key to exit'#13#10);
  Asm Mov Ah,0{- Read from Keyboard -}
  Asm Int 16h;

END. {Main}

corner
© 1996-2008 CommunityHeaven LLC. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
North American business development: Nicolai Wadstrom. Publisher: Lars Hagelin.