flat assembler
Message board for the users of flat assembler.

Index > Projects and Ideas > IDEA : FIX 3 files to only one...

Author
Thread Post new topic Reply to topic
Remy Vincent



Joined: 16 Sep 2005
Posts: 155
Location: France
Remy Vincent
I am so sorry to post PASCAL code in this FASM FORUM, but it is so VERY HARD to write this kind of algorithm directly in assembler, my god,... even transalting it from pascal ==> asm looks like a year work!!! BUT... this "small program" is fully tested (as I am used to)!!!

Code:
PROGRAM   Cmp3File ;
{$IFDEF MSDOS}   USES   DOS ;   {$ENDIF}      {--- TP4,... }
{$IFDEF DPMI}    USES   DOS ;   {$ENDIF}
{$IFDEF WIN32}   {$APPTYPE CONSOLE}   USES   SysUtils ;   {$ENDIF}      {--- Delphi2,... }

{$IFDEF MSDOS}   {$DEFINE MSDOS_DPMI}   {$ENDIF}
{$IFDEF DPMI}    {$DEFINE MSDOS_DPMI}   {$ENDIF}

{
!------------------------------------------------------------------------------
! Small Toolbox
!------------------------------------------------------------------------------
}
{$IFDEF MSDOS_DPMI}
{
!---------------
! String routines
!---------------
! UpperCase
!---------------
}
{===== UpperCase }

FUNCTION   UpperCase   ( IL_String : String ) : String ;
VAR
   L_i : Integer ;
BEGIN
   FOR L_i := 1 TO Length(IL_String) DO BEGIN
      IL_String[L_i] := UpCase ( IL_String[L_i] );
   END;
   UpperCase := IL_String ;
END;
{$ENDIF}

{$IFDEF MSDOS_DPMI}
{
!---------------
! FileExists
!---------------
}
{===== FileExists }

FUNCTION   FileExists   ( I_Path : String ) : Boolean ;
VAR
   L_SearchRec : SearchRec ;
BEGIN
   FindFirst ( I_Path , AnyFile , L_SearchRec );
   FileExists := ( DosError = 0 );
END;
{$ENDIF}


{===============}


VAR
   GI_FilePath1 : String ;      {--- Parameter 1 }
   GI_FilePath2 : String ;      {--- Parameter 2 }
   GI_FilePath3 : String ;      {--- Parameter 3 }

   GI_OutFilePath : String ;      {--- Parameter 4 }

   G_VerboseQ : Boolean ;

VAR
   G_Buffer1 : Array[0..2047] of Byte ;
   G_Buffer2 : Array[0..2047] of Byte ;
   G_Buffer3 : Array[0..2047] of Byte ;
   G_File1   : File ;
   G_File2   : File ;
   G_File3   : File ;
   G_ByteRead1 : {$IFDEF WIN32}Longint{$ELSE}Word{$ENDIF} ;
   G_ByteRead2 : {$IFDEF WIN32}Longint{$ELSE}Word{$ENDIF} ;
   G_ByteRead3 : {$IFDEF WIN32}Longint{$ELSE}Word{$ENDIF} ;

   G_OutBuffer : Array[0..2047] of Byte ;
   G_OutFile   : File ;
   G_ByteToWrite : Word ;

   G_iSegment : Longint ;

   G_jCountMin : Word ;
   {--G_jCountMax : Word ;--}
   G_jNextStep : Shortint ;

   G_jCount : Word ;
   G_j      : Word ;
   G_Byte1  : Byte ;
   G_Byte2  : Byte ;
   G_Byte3  : Byte ;

VAR
   G_HelpUP : String[10];

BEGIN
   {===== Help ========================================================= }
   G_HelpUP := UpperCase ( ParamStr(1) );
   IF (G_HelpUP = '?'   ) Or (G_HelpUP = '-?'   ) Or (G_HelpUP = '/?'   ) Or
      (G_HelpUP = 'HELP') Or (G_HelpUP = '-HELP') Or (G_HelpUP = '/HELP') Or
      (ParamCount = 0)
   THEN BEGIN
      WriteLn (   '***** Cmp3File Help ***********************************************************'   );
      WriteLn (   'Process 3 Binary files, and output the "best choice" when the bytes'               );
      WriteLn (   'of the 3 files are different.'                                                     );
      WriteLn (   '- This program is made to "try to repair" 3 corrupted versions'                    );
      WriteLn (   '  of the same file.'                                                               );
      WriteLn (   '- (  "Cmp3File"  means  "CoMPare, 3 FILEs"  )'                                     );
      WriteLn (   ''                                                                                  );
      WriteLn (   'CMP3FILE   FilePath1   FilePath2   FilePath3   [OutFilePath]   [>Destination]'     );
      WriteLn (   ''                                                                                  );
      WriteLn (   '   FilePath1   : The existing binary file, copy 1.'                                );
      WriteLn (   '   FilePath2   : The existing binary file, copy 2.'                                );
      WriteLn (   '   FilePath3   : The existing binary file, copy 3.'                                );
      WriteLn (   '   OutFilePath : The "best byte choice", when the 3 files are different.'          );
      WriteLn (   '   Destination : Default is screen, to output to a file use usual'                 );
      WriteLn (   '                 "DOS output redirection"  ( CMD  ...  >MyOutput.TXT ).'           );
      WriteLn (   ''                                                                                  );
      WriteLn (   '----- Examples :'                                                                  );
      WriteLn (   'Cmp3File   DownLd1.BIN   DownLd2.BIN   DownLd3.BIN   Repaired.BIN'                 );
      WriteLn (   'Cmp3File   DownLd1.BIN   DownLd2.BIN   DownLd3.BIN   Repaired.BIN   >errors.out'   );
      WriteLn (   '*******************************************************************************'   );

      HALT ( 0 );
   END;

   {----- CONTROL Parameter 1 : File exists ?  }
   GI_FilePath1 := ParamStr(1);
   IF not FileExists ( GI_FilePath1 ) THEN BEGIN
      WriteLn (   'ERROR: '  ,  'File1 not found  ( Parameter 1 ).'   );
      HALT ( 1 );
   END;

   {----- CONTROL Parameter 2 : File exists ?  }
   GI_FilePath2 := ParamStr(2);
   IF not FileExists ( GI_FilePath2 ) THEN BEGIN
      WriteLn (   'ERROR: '  ,  'File2 not found  ( Parameter 2 ).'   );
      HALT ( 1 );
   END;

   {----- CONTROL Parameter 3 : File exists ?  }
   GI_FilePath3 := ParamStr(3);
   IF not FileExists ( GI_FilePath3 ) THEN BEGIN
      WriteLn (   'ERROR: '  ,  'File3 not found  ( Parameter 3 ).'   );
      HALT ( 1 );
   END;

   {----- OPTIONAL : Parameter 4 }
   GI_OutFilePath := ParamStr(4);

   G_VerboseQ := TRUE ;


   Assign ( G_File1 , GI_FilePath1 );
   Reset  ( G_File1 , 1 );

   Assign ( G_File2 , GI_FilePath2 );
   Reset  ( G_File2 , 1 );

   Assign ( G_File3 , GI_FilePath3 );
   Reset  ( G_File3 , 1 );

   IF GI_OutFilePath <> '' THEN BEGIN
      Assign  ( G_OutFile , GI_OutFilePath );
      Rewrite ( G_OutFile , 1 );
   END;

   G_iSegment := 1 ;

   {----- LOOP , Read the 3 binary files , with 3 small buffers }
   WHILE (Eof(G_File1) = False) Or (Eof(G_File2) = False) Or (Eof(G_File3) = False)
   DO BEGIN
      {----- Input : Binary file 1, 2 & 3 }
      BlockRead ( G_File1 , G_Buffer1[0] , SizeOf(G_Buffer1) , G_ByteRead1 );
      BlockRead ( G_File2 , G_Buffer2[0] , SizeOf(G_Buffer2) , G_ByteRead2 );
      BlockRead ( G_File3 , G_Buffer3[0] , SizeOf(G_Buffer3) , G_ByteRead3 );

      {--------------- DECISION, Find the smaller buffer ---------------}

      {----- Find min length }
      IF G_ByteRead1 = G_ByteRead2
      THEN BEGIN
         IF G_ByteRead1 = G_ByteRead3
         THEN BEGIN   { usual case }
            G_jCountMin := G_ByteRead1 ;
            G_jNextStep := 0 ;      {--- No next step needed, because 3 buffer length equal }
         END
         ELSE BEGIN
            IF G_ByteRead3 < G_ByteRead1
            THEN BEGIN
               G_jCountMin := G_ByteRead3 ;
               G_jNextStep := -3 ;      {--- Next step WITHOUT buffer 3 }
            END
            ELSE BEGIN
               G_jCountMin := G_ByteRead1 ;
               G_jNextStep := 3 ;      {--- Next step WITH ONLY buffer 3 }
            END;
         END
      END
      ELSE BEGIN
         IF G_ByteRead1 = G_ByteRead3
         THEN BEGIN
            IF G_ByteRead2 < G_ByteRead1
            THEN BEGIN
               G_jCountMin := G_ByteRead2 ;
               G_jNextStep := -2 ;      {--- Next step WITHOUT buffer 2 }
            END
            ELSE BEGIN
               G_jCountMin := G_ByteRead1 ;
               G_jNextStep := 2 ;      {--- Next step WITH ONLY buffer 2 }
            END;
         END
         ELSE BEGIN
            IF G_ByteRead2 = G_ByteRead3
            THEN BEGIN
               IF G_ByteRead1 < G_ByteRead2
               THEN BEGIN
                  G_jCountMin := G_ByteRead1 ;
                  G_jNextStep := -1 ;      {--- Next step WITHOUT buffer 1 }
               END
               ELSE BEGIN
                  G_jCountMin := G_ByteRead2 ;
                  G_jNextStep := 1 ;      {--- Next step WITH ONLY buffer 1 }
               END;
            END;
         END;
      END;

      {--------------- MAIN, 3 buffers(COMMON PARTS)  ==>  Best choice ---------------}

      G_ByteToWrite := 0 ;
      G_j := 0 ;
      G_jCount := G_jCountMin ;

      {----- LOOP 1 : Compare each byte }
      WHILE G_jCount <> 0 DO BEGIN
         G_Byte1 := G_Buffer1[G_j];
         G_Byte2 := G_Buffer2[G_j];
         G_Byte3 := G_Buffer3[G_j];

         {----- Big choice, because which bytes are equal ?  }
         IF G_Byte1 = G_Byte2
         THEN BEGIN
            IF G_Byte1 = G_Byte3
            THEN BEGIN
               G_OutBuffer[G_j] := G_Byte1 ;
            END
            ELSE BEGIN
               G_OutBuffer[G_j] := G_Byte1 ;

               IF G_VerboseQ
               THEN WriteLn (   G_iSegment  ,  ':'  ,  G_j  ,  '> '
                             ,  G_Byte1  ,  ' '  ,  G_Byte2  ,  ' ('  ,  G_Byte3  ,  ')'
                            );
            END;
         END
         ELSE BEGIN
            IF G_Byte1 = G_Byte3
            THEN BEGIN
               G_OutBuffer[G_j] := G_Byte1 ;

               IF G_VerboseQ
               THEN WriteLn (   G_iSegment  ,  ':'  ,  G_j  ,  '> '
                             ,  G_Byte1  ,  ' ('  ,  G_Byte2  ,  ') '  ,  G_Byte3   );
            END
            ELSE BEGIN
               IF G_Byte2 = G_Byte3
               THEN BEGIN
                  G_OutBuffer[G_j] := G_Byte2 ;

                  IF G_VerboseQ
                  THEN WriteLn (   G_iSegment  ,  ':'  ,  G_j  ,  '> '
                                ,  '('  ,  G_Byte1  ,  ') '  ,  G_Byte2  ,  ' '  ,  G_Byte3   );
               END
               ELSE BEGIN
                  G_OutBuffer[G_j] := G_Byte1 ;      {--- Default choice when the 3 bytes are different }

                  IF G_VerboseQ
                  THEN WriteLn (   G_iSegment  ,  ':'  ,  G_j  ,  '> '
                                ,  '('  ,  G_Byte1  ,  ') ('  ,  G_Byte2  ,  ') ('  ,  G_Byte3  ,  ')'   );
               END;
            END;
         END;

         DEC ( G_jCount );
         Inc ( G_j );
         {--Inc ( G_ByteToWrite );--}
      END;{while}

      G_ByteToWrite := G_jCountMin ;

      Dec ( G_ByteRead1 , G_jCountMin );
      Dec ( G_ByteRead2 , G_jCountMin );
      Dec ( G_ByteRead3 , G_jCountMin );

      {--------------- 2 buffers(ENDING PARTS)  ==>  Best choice ---------------}

      CASE G_jNextStep OF
         -3 : BEGIN   { Step WITHOUT buffer 3 }
            {----- Find  min length }
            IF G_ByteRead1 = G_ByteRead2
            THEN BEGIN
               G_jCountMin := G_ByteRead1 ;
               G_jNextStep := 0 ;      {--- No next step needed }
            END
            ELSE BEGIN
               IF G_ByteRead1 < G_ByteRead2
               THEN BEGIN
                  G_jCountMin := G_ByteRead1 ;
                  G_jNextStep := 2 ;      {--- Next step WITH ONLY buffer 2 }
               END
               ELSE BEGIN
                  G_jCountMin := G_ByteRead2 ;
                  G_jNextStep := 1 ;      {--- Next step WITH ONLY buffer 1 }
               END;
            END;

            G_jCount := G_jCountMin ;

            {----- LOOP 2.3 : Compare each byte }
            WHILE G_jCount <> 0 DO BEGIN
               G_Byte1 := G_Buffer1[G_j];
               G_Byte2 := G_Buffer2[G_j];

               {----- Choice, bytes are equal ?  }
               IF G_Byte1 = G_Byte2
               THEN BEGIN
                  G_OutBuffer[G_j] := G_Byte1 ;
               END
               ELSE BEGIN
                  G_OutBuffer[G_j] := G_Byte1 ;      {--- Default choice when the 2 bytes are different }

                  IF G_VerboseQ
                  THEN WriteLn (   G_iSegment  ,  ':'  ,  G_j  ,  '> '
                                ,  G_Byte1  ,  ' ('  ,  G_Byte2  ,  ') ('  ,  ';'  ,  ')'   );
               END;

               DEC ( G_jCount );
               Inc ( G_j );
               {--Inc ( G_ByteToWrite );--}
            END;{while}

            Inc ( G_ByteToWrite , G_jCountMin );

            Dec ( G_ByteRead1 , G_jCountMin );
            Dec ( G_ByteRead2 , G_jCountMin );
         END;

         -2 : BEGIN   { Step WITHOUT buffer 2 }
            {----- Find  min length }
            IF G_ByteRead1 = G_ByteRead3
            THEN BEGIN
               G_jCountMin := G_ByteRead1 ;
               G_jNextStep := 0 ;      {--- No next step needed }
            END
            ELSE BEGIN
               IF G_ByteRead1 < G_ByteRead3
               THEN BEGIN
                  G_jCountMin := G_ByteRead1 ;
                  G_jNextStep := 3 ;      {--- Next step WITH ONLY buffer 3 }
               END
               ELSE BEGIN
                  G_jCountMin := G_ByteRead3 ;
                  G_jNextStep := 1 ;      {--- Next step WITH ONLY buffer 1 }
               END;
            END;

            G_jCount := G_jCountMin ;

            {----- LOOP 2.2 : Compare each byte }
            WHILE G_jCount <> 0 DO BEGIN
               G_Byte1 := G_Buffer1[G_j];
               G_Byte3 := G_Buffer3[G_j];

               {----- Choice, bytes are equal ?  }
               IF G_Byte1 = G_Byte3
               THEN BEGIN
                  G_OutBuffer[G_j] := G_Byte1 ;
               END
               ELSE BEGIN
                  G_OutBuffer[G_j] := G_Byte1 ;      {--- Default choice when the 2 bytes are different }

                  IF G_VerboseQ
                  THEN WriteLn (   G_iSegment  ,  ':'  ,  G_j  ,  '> '
                                ,  G_Byte1  ,  ' ('  ,  '.'  ,  ') ('  ,  G_Byte3  ,  ')'   );
               END;

               DEC ( G_jCount );
               inc ( G_j );
               {--Inc ( G_ByteToWrite );--}
            END;{while}

            Inc ( G_ByteToWrite , G_jCountMin );

            Dec ( G_ByteRead1 , G_jCountMin );
            Dec ( G_ByteRead3 , G_jCountMin );
         END;

         -1 : BEGIN   { Step WITHOUT buffer 1 }
            {----- Find  min length }
            IF G_ByteRead2 = G_ByteRead3
            THEN BEGIN
               G_jCountMin := G_ByteRead2 ;
               G_jNextStep := 0 ;      {--- No next step needed }
            END
            ELSE BEGIN
               IF G_ByteRead2 < G_ByteRead3
               THEN BEGIN
                  G_jCountMin := G_ByteRead2 ;
                  G_jNextStep := 3 ;      {--- Next step WITH ONLY buffer 3 }
               END
               ELSE BEGIN
                  G_jCountMin := G_ByteRead3 ;
                  G_jNextStep := 2 ;      {--- Next step WITH ONLY buffer 2 }
               END;
            END;

            G_jCount := G_jCountMin ;

            {----- LOOP 2.3 : Compare each byte }
            WHILE G_jCount <> 0 DO BEGIN
               G_Byte2 := G_Buffer2[G_j];
               G_Byte3 := G_Buffer3[G_j];

               {----- Choice, bytes are equal ?  }
               IF G_Byte2 = G_Byte3
               THEN BEGIN
                  G_OutBuffer[G_j] := G_Byte2 ;
               END
               ELSE BEGIN
                  G_OutBuffer[G_j] := G_Byte2 ;      {--- Default choice when the 2 bytes are different }

                  IF G_VerboseQ
                  THEN WriteLn (   G_iSegment  ,  ':'  ,  G_j  ,  '> '
                                ,  '('  ,  '.'  ,  ') '  ,  G_Byte2  ,  ' ('  ,  G_Byte3  ,  ')'   );
               END;

               DEC ( G_jCount );
               Inc ( G_j );
               {--Inc ( G_ByteToWrite );--}
            END;{while}

            Inc ( G_ByteToWrite , G_jCountMin );

            Dec ( G_ByteRead2 , G_jCountMin );
            Dec ( G_ByteRead3 , G_jCountMin );
         END;

         0 : ;   { No next step needed }

         1 : BEGIN   { Step WITH ONLY buffer 1 }
            {----- Min length }
            G_jCountMin := G_ByteRead1 ;
            G_jNextStep := 0 ;      {--- No next step needed }

            G_jCount := G_jCountMin ;

            Move ( G_Buffer1[G_j] , G_OutBuffer[G_j] , G_jCount );

            Inc ( G_ByteToWrite , G_jCountMin );

            Dec ( G_ByteRead1 , G_jCountMin );
         END;

         2 : BEGIN   { Step WITH ONLY buffer 2 }
            {----- Min length }
            G_jCountMin := G_ByteRead2 ;
            G_jNextStep := 0 ;      {--- No next step needed }

            G_jCount := G_jCountMin ;

            Move ( G_Buffer2[G_j] , G_OutBuffer[G_j] , G_jCount );

            Inc ( G_ByteToWrite , G_jCountMin );

            Dec ( G_ByteRead2 , G_jCountMin );
         END;

         3 : BEGIN   { Step WITH ONLY buffer 3 }
            {----- Min length }
            G_jCountMin := G_ByteRead3 ;
            G_jNextStep := 0 ;      {--- No next step needed }

            G_jCount := G_jCountMin ;

            Move ( G_Buffer3[G_j] , G_OutBuffer[G_j] , G_jCount );

            Inc ( G_ByteToWrite , G_jCountMin );

            Dec ( G_ByteRead3 , G_jCountMin );
         END;
      END;{case}

      Inc ( G_ByteToWrite , G_ByteRead3 );

      {--------------- One buffer(ENDING PART)  ==>  Best choice ---------------}

      CASE G_jNextStep OF
         0 : ;   { No next step needed }

         1 : BEGIN   { Step WITH ONLY buffer 1 }
            {----- Min length }
            G_jCountMin := G_ByteRead1 ;
            G_jNextStep := 0 ;      {--- No next step needed }

            G_jCount := G_jCountMin ;

            Move ( G_Buffer1[G_j] , G_OutBuffer[G_j] , G_jCount );

            Inc ( G_ByteToWrite , G_jCountMin );

            Dec ( G_ByteRead1 , G_jCountMin );
         END;

         2 : BEGIN   { Step WITH ONLY buffer 2 }
            {----- Min length }
            G_jCountMin := G_ByteRead2 ;
            G_jNextStep := 0 ;      {--- No next step needed }

            G_jCount := G_jCountMin ;

            Move ( G_Buffer2[G_j] , G_OutBuffer[G_j] , G_jCount );

            Inc ( G_ByteToWrite , G_jCountMin );

            Dec ( G_ByteRead2 , G_jCountMin );
         END;

         3 : BEGIN   { Step WITH ONLY buffer 3 }
            {----- Min length }
            G_jCountMin := G_ByteRead3 ;

            G_jCount := G_jCountMin ;

            Move ( G_Buffer3[G_j] , G_OutBuffer[G_j] , G_jCount );

            Inc ( G_ByteToWrite , G_jCountMin );

            Dec ( G_ByteRead3 , G_jCountMin );
         END;
      END;{case}

      {--------------- / ---------------}

      {----- OUTPUT : Selected bytes }
      IF GI_OutFilePath <> '' THEN BEGIN
         BlockWrite ( G_OutFile , G_OutBuffer[0] , G_ByteToWrite );
      END;

      INC ( G_iSegment );
   END;{while}

   Close ( G_File1 );
   Close ( G_File2 );
   Close ( G_File3 );

   IF GI_OutFilePath <> '' THEN BEGIN
      Close ( G_OutFile );
   END;
END.
    

[/code]
Post 23 Nov 2006, 22:50
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7106
Location: Slovakia
vid
can't help myself, but i believe this program could be written much more efficiently. Could you please explain closer what it does?
Post 23 Nov 2006, 23:04
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16847
Location: In your JS exploiting you and your system
revolution
Looks like a vaiant of a simple majority rules selection using byte by byte comparison. Although I can't understand why the files would be currupted in such a way unless he/she has unreliable RAM or HDD.
Post 23 Nov 2006, 23:16
View user's profile Send private message Visit poster's website Reply with quote
Remy Vincent



Joined: 16 Sep 2005
Posts: 155
Location: France
Remy Vincent
Some weeks ago, I tried to download some BORLAND programs: from their "external but borland" web site .turboexplorer. : english version of Turbo delphi was unpacking, but not french version of TURBODELPHI,... so I tried to download 3 times, and as I am unlucky, the 3 files were unable to unpack... That's why I tried to do the previous very hard algorithm, to be able to join, and fix, 3 corrupted files... but may be too much reading is less clear than a "graphical" explanation:

- DOWLOADED FILE 1 (unable to unpack)
- DOWLOADED FILE 2 (unable to unpack too)
- DOWLOADED FILE 3 (unable to unpack also)

CMP3FILE.exe "Fil_1.exe" "Fil_2.exe" "Fil_3.exe" TRYTOFIXIT.exe



This is what I call "IDEA : FIX 3 files to only one..."

Is it possible in FASM?? or are we REACHING THE "ROOF" of what could be done with assembler???

That is a question: does assembler programming aloud very complex algorithms... Yeah, what could absolutly be impossible to program only with assembler, without any call to any external DLL done in another High Level Language???
Post 23 Nov 2006, 23:18
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Using arrays instead of "VarNameX" where X is in 1..3 can help a lot. For the part that choose the minimun can be done by first sorting the array and then picking the appropiate cell. Rewrite it using arrays, it will make the job of porting it to fasm easier IMHO
Post 24 Nov 2006, 00:20
View user's profile Send private message Reply with quote
Remy Vincent



Joined: 16 Sep 2005
Posts: 155
Location: France
Remy Vincent
LocoDelAssembly wrote:
Using arrays instead of "VarNameX" where X is in 1..3 can help a lot. For the part that choose the minimun can be done by first sorting the array and then picking the appropiate cell. Rewrite it using arrays, it will make the job of porting it to fasm easier IMHO


?
With a vararray, do you think it would be possible to process more than 8 or 9 files with less program lines than the program lines needed to process 3 files ?
Post 24 Nov 2006, 00:56
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7106
Location: Slovakia
vid
now i understand. here is the idea for "find min length" and "common parts". Which is MUCH nicer in assembly (gotos) than in HLL

Code:
;load values to registers
mov ebx, [G_ByteRead1]
mov ecx, [G_ByteRead2]
mov edx, [G_ByteRead3]

;find min count
mov eax, ebx
cmp eax, ecx
cmova eax, ecx
cmp eax, edx
cmova eax, edx
mov [G_jMinCount], eax

;determine next step
;check case 1=2
cmp ebx, ecx
jne @f

mov eax, 0
cmp ebx, edx
je .next_step_done

mov eax, -3
cmp edx, ebx
jl .next_step_done

mov eax, 3
jmp .next_step_done

;check case 1=3
@@:
cmp ebx, edx
jne @f

mov eax,-2
cmp ecx, ebx
jl .next_step_done

mov eax, 2
jmp .next_step_done

;check case 2=3
@@:
cmp ecx, edx
jne .next_step_done ;in this case you don't set those variables at all

mov eax, -1
cmp ebx, ecx
je .next_step_done

mov eax, 1

.next_step_done:
mov [G_jNextStep], eax
    


you see, no problem


Last edited by vid on 24 Nov 2006, 02:38; edited 2 times in total
Post 24 Nov 2006, 01:09
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7106
Location: Slovakia
vid
in fact, whenever you see something like this:
Code:
     end;
    end;
   end;
  end;
 end;    


then you can be sure it can be writen nice in ASM Wink
Post 24 Nov 2006, 01:12
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Your algorithm is too big to fit in my brain so forgive me if the following pseudo-code is not what you spected Razz:
Code:
first we read all file into their respective buffers at the array

We find the which is the most amount of bytes read this way:

max_size := -1;
FOR i:= 1 TO N DO IF files[i].G_ByteRead > max then max := files[i].G_ByteRead; { This part is incredible easy with ASM if you have a PPro class CPU Very Happy (look at vid's code above) }

Now that we know which buffers has max_size bytes we compare all of them to see which one has more coincidences:

max_occurrencies:= 0;
max_buffer := 1;

FOR i := 1 to N DO
BEGIN
  IF files[i].files[i].G_ByteRead < max then continue; {skip this step}
  ocurrencies := 0;
  FOR j := i+1 to N DO IF files[i].buffer = files[j].buffer THEN inc(ocurrencies);
  IF ocurrencies > max_occurrencies THEN
  BEGIN
    max_buffer := i;
    max_occurrencies := occurrencies;
  END;
END;

At this point we know which data pattern appeared more times (if a tie occured then the tie-break has been made by choosing the first pattern with max_occurrencies occurrencies).    
Post 24 Nov 2006, 01:50
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7416
Location: Kraków, Poland
Tomasz Grysztar
Remy Vincent wrote:
That is a question: does assembler programming aloud very complex algorithms... Yeah, what could absolutly be impossible to program only with assembler, without any call to any external DLL done in another High Level Language???

Nothing would be impossible. On the other hand, some things are impossible to program only with HLL without call to assembly. Wink
And, as vid already noted, the branches allow to write algorithms in more compact and cleaner form that structural code, if only you know how to use them wisely.
You also wouldn't be able to convert fasm's source into a structural form without re-arranging many parts - while converting structural code into a branched one is pretty straightforward. (Well, this is all about jumps really, not the assembly itself*. I personally very dislike languages - even though I'm sometimes forced to use them - that don't have GOTO statement... I can manage to handle problems using purely structural code, I just don't get why people hate GOTO so much... perhaps they are scared of too much power it would give to them).

---
* Still the assembly has more of the nice "outside-paradigm" tricks. Recently I had trouble converting into HLL code like:
Code:
cmp [variable],100
ja is_above
jb is_below
; here we do something when it's equal    

You see, it's usually impossible (without writing a macro or something like that) to do such construction in HLL without writing the name of variable twice.
Post 24 Nov 2006, 09:56
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7106
Location: Slovakia
vid
yes the problem with new languages is power. Power can always be misused, and todays trend is to reduce power to disallow coder misuse anything. That's why C programmers say gotos are stupid, and why C# programmers say pointers are stupid. Everything powerful can be misused, but that is not reason not to use it
Post 24 Nov 2006, 13:40
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Quote:
I just don't get why people hate GOTO so much... perhaps they are scared of too much power it would give to them).


Because we learn that shit at university and to be sure that you will not have "strange ideas" of using it them disapprove you at the exams and even force you to take the course again the next year if you persist with your "revolutionary ideas". And all this shit is because they promise you that with structured code you will produce bug free code just because the blocks has one entry point and one exit point and apparently this will avoid returning wrong values at the end of the module (which has to have only one return point too...). Note that if you produce a 100 lines code using goto over the same code using structured code but with 1000 lines they still thinking that structured code is better Mad

University concepts sucks Smile You learn great things at there but unfortunately they cut your creativity by things like this and some courses goes beyond and disapprove you if you write an algorithm in a way not seen at the course and no matter if your algorithm is better and uses HLL constructs seen at the course :S
Post 24 Nov 2006, 14:48
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2019, Tomasz Grysztar.

Powered by rwasa.