[Back to STRINGS SWAG index]  [Back to Main SWAG index]  [Original]

{From:         Joel Lichtenwalner <JWillard44@AOL.COM>}

PROGRAM TEST_CONCAT;  { TESTS VARIOUS METHODS OF CONCATENATING STRINGS }

  USES
    CRT;

  CONST
    ADD_STR     : STRING[22] = 'Test string 1234567890';
    TICKS       = 90;           { LOOP FOR APPROX 5 SECONDS }

  VAR

    CLOCK_TICKS : WORD ABSOLUTE $40:$6C;  { Updated every 58 ms by system }
    TIME_SAVE   : WORD;         { Variable used to keep track of time     }
    LOOPS       : LONGINT;      { Loop control counter                    }
    TARG        : STRING[255];  { Target string, to be added too          }
    COMPUTE     : EXTENDED;


  function strcont(s1,s2:string):string; assembler;
    asm
      push ds
      cld
      lds si,s1         {Load addresses of s1}
      les di,s2         {Load addresses of s2}
      xor ah,ah         {Clear ah & bh}
      xor bh,bh         {     ""      }
      mov al,ds:[si]    {Get the length of first string, copy into al}
      mov bl,es:[di]    {Get the length of second string, copy into bl}
      add ax,bx         {Add length of s1 to length s2}
      cmp ax,255        {Compare}
      ja @toolarge      {Jump to @toolarge if length(s1)+length(s2)>255}
      les di,@result    {Copy location of @result into es:di}
      mov cl,1          {Make sure at least one byte of beginning string}
      xor ch,ch         {is transferred to @result.}
      add cl,ds:[si]    {Add length of string to cl.}
      rep movsb         {Copy first string into @result}
      lds si,s2         {Get address of second string}
      mov cl,ds:[si]    {Get length of second string, copy into cl}
      cmp cl,0          {If second string is blank, skip adding it.}
      je @end           {Jump to end if length of second string is zero.}
      inc si            {Move pointer (si) to start of second string}
      mov al,cl         {Save length of second string in al}
      rep movsb         {Copy second string into @result}
      lds si,@result    {Get location of @result}
      add ds:[si],al    {Add lengths together}
      jmp @end          {Skip to end}
     @toolarge:         {If added strings total larger than 255, this sub}
      les di,@result    {is called.}
      xor al,al         {Make sure al is a zero.}
      mov es:[di],al    {Move a "0" into the beginning of @result, making it}
     @end:              {a null string.}
      pop ds            {Return DS to normal so Pascal doesn't screw up.}
      end;

  PROCEDURE ATTACH(VAR DEST,SOURCE:STRING);

    VAR
        DESTL   : BYTE ABSOLUTE DEST;
        SOURCEL : BYTE ABSOLUTE SOURCE;
      BEGIN
        MOVE(SOURCE[1],DEST[SUCC(DESTL)],SOURCEL);
        INC(DESTL,SOURCEL);
        END;
    BEGIN
      CLRSCR;  WRITELN('Test concatenation functions');
      { -------- FIRST TEST -------- }
      WRITE('Testing Pascal''s "+" function');
      LOOPS := 0;
      TIME_SAVE := CLOCK_TICKS;    { WAIT UNTIL THE CLOCK TURNS OVER }
      REPEAT UNTIL CLOCK_TICKS <> TIME_SAVE;
      TIME_SAVE := CLOCK_TICKS + TICKS;  { Set loop time }
        REPEAT
        TARG := '';
        TARG := TARG + ADD_STR;  {  22 }
        TARG := TARG + ADD_STR;  {  44 }
        TARG := TARG + ADD_STR;  {  66 }
        TARG := TARG + ADD_STR;  {  88 }
        TARG := TARG + ADD_STR;  { 110 }
        TARG := TARG + TARG;     { 220 }
        TARG := TARG + ADD_STR;  { 242 }
        INC(LOOPS);
        UNTIL CLOCK_TICKS = TIME_SAVE;
      COMPUTE := LOOPS; COMPUTE := COMPUTE / TICKS;
      WRITELN(' Performance = ',COMPUTE:0:6,' Loops per tick');
      { -------- SECOND TEST -------- }
      WRITE('Testing STRCONT function');
      LOOPS := 0;
      TIME_SAVE := CLOCK_TICKS;    { WAIT UNTIL THE CLOCK TURNS OVER }
      REPEAT UNTIL CLOCK_TICKS <> TIME_SAVE;
      TIME_SAVE := CLOCK_TICKS + TICKS;  { Set loop time }
        REPEAT
        TARG := '';
        TARG := strcont(TARG,ADD_STR);  {  22 }
        TARG := strcont(TARG,ADD_STR);  {  44 }
        TARG := strcont(TARG,ADD_STR);  {  66 }
        TARG := strcont(TARG,ADD_STR);  {  88 }
        TARG := strcont(TARG,ADD_STR);  { 110 }
        TARG := strcont(TARG,TARG);     { 220 }
        TARG := strcont(TARG,ADD_STR);  { 242 }
        INC(LOOPS);
        UNTIL CLOCK_TICKS = TIME_SAVE;
      COMPUTE := LOOPS; COMPUTE := COMPUTE / TICKS;
      WRITELN(' Performance = ',COMPUTE:0:6,' Loops per tick');
      { -------- THIRD TEST -------- }
      WRITE('Testing ATTACH procedure ');
      LOOPS := 0;
      TIME_SAVE := CLOCK_TICKS;    { WAIT UNTIL THE CLOCK TURNS OVER }
      REPEAT UNTIL CLOCK_TICKS <> TIME_SAVE;
      TIME_SAVE := CLOCK_TICKS + TICKS;  { Set loop time }
        REPEAT
        TARG := '';
        ATTACH(TARG,ADD_STR);  {  22 }
        ATTACH(TARG,ADD_STR);  {  44 }
        ATTACH(TARG,ADD_STR);  {  66 }
        ATTACH(TARG,ADD_STR);  {  88 }
        ATTACH(TARG,ADD_STR);  { 110 }
        ATTACH(TARG,TARG);     { 220 }
        ATTACH(TARG,ADD_STR);  { 242 }
        INC(LOOPS);
        UNTIL CLOCK_TICKS = TIME_SAVE;
      COMPUTE := LOOPS; COMPUTE := COMPUTE / TICKS;
      WRITELN(' Performance = ',COMPUTE:0:6,' Loops per tick');
      READLN;
      END.


[Back to STRINGS SWAG index]  [Back to Main SWAG index]  [Original]