[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]