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

    {  Ok here it is..   I have disasembled the following TP Program to
    show you the inner workings of TP (well at least 6.0).  The
    Folloing Program was Compiled in the IDE With RANGE, I/O, STACK
    checking turned off.  Look at the code close and see if you can
    find a nasty little bug in it beFore I show you the Asm that TP
    Created on disk.
    }

    Program TstFiles;

    Type MyRec = Record
                   LInt : LongInt;
                   Hi   : Word;
                   Lo   : Word;
                   B1   : Byte;
                   B2   : Byte;
                   B3   : Byte;
                   B4   : Byte;
                 end;            {Record Size 12 Bytes}

    Const MaxRecs = 100;

    Var MyTypedFile   : File of MyRec;
        MyUnTypedFile : File;

        Rec           : MyRec;
        RecCnt        : Word;

    Procedure FillRec (RecSeed : LongInt);

      begin
      Rec.Lint := RecSeed;
      Rec.Hi   := Hi (Rec.Lint);
      Rec.Lo   := Lo (Rec.Lint);
      Rec.B1   := Lo (Rec.Lo);
      Rec.B2   := Hi (Rec.Lo);
      Rec.B3   := Lo (Rec.Hi);
      Rec.B4   := Hi (Rec.Hi);
      end;

    begin
    Assign  (MyTypedFile,   'Type.Dat');
    Assign  (MyUnTypedFile, 'UnTyped.Dat');
    ReWrite (MyTypedFile);
    ReWrite (MyUnTypedFile);

    For RecCnt := 1 to MaxRecs do
      begin
      FillRec (RecCnt);

      Write (MyTypedFile  , Rec);
    { Write (MyUnTypedFile, Rec);} {Illegal can't do this}

      FillRec (RecCnt + $FFFF);

    { BlockWrite (MyTypedFile, Rec, 1);} {Illegal Can't do this eather}

      BlockWrite (MyUnTypedFile, Rec, Sizeof (MyRec));
      end;

    end.

    The Asm Break down is in the next two messages...

    TSTFileS.38: begin
      cs:0051 9A0000262D     call   2D26:0000 <-------TP Start Up Code
      cs:0056 55             push   bp
      cs:0057 89E5           mov    bp,sp
    TSTFileS.39: Assign (MyTypedFile, 'Type.Dat');
      cs:0059 BF4400         mov    di,0044
      cs:005C 1E             push   ds
      cs:005D 57             push   di
      cs:005E BF3C00         mov    di,003C
      cs:0061 0E             push   cs
      cs:0062 57             push   di
      cs:0063 9AC004262D     call   2D26:04C0 <-------TP's Routine to set
                                                      up File Records.
    TSTFileS.40: Assign (MyUnTypedFile, 'UnTyped.Dat');
      cs:0068 BFC400         mov    di,00C4
      cs:006B 1E             push   ds
      cs:006C 57             push   di
      cs:006D BF4500         mov    di,0045
      cs:0070 0E             push   cs
      cs:0071 57             push   di
      cs:0072 9AC004262D     call   2D26:04C0 <-------TP's Routine to set
                                                      up File Records.
    TSTFileS.41: ReWrite (MyTypedFile);
      cs:0077 BF4400         mov    di,0044
      cs:007A 1E             push   ds
      cs:007B 57             push   di
      cs:007C B80C00         mov    ax,000C
      cs:007F 50             push   ax
      cs:0080 9AF704262D     call   2D26:04F7 <-------TP's Routine to
                                                      Create File.
    TSTFileS.42: ReWrite (MyUnTypedFile);
      cs:0085 BFC400         mov    di,00C4
      cs:0088 1E             push   ds
      cs:0089 57             push   di
      cs:008A B88000         mov    ax,0080
      cs:008D 50             push   ax
      cs:008E 9AF704262D     call   2D26:04F7 <-------TP's Routine to
                                                      Create File.
    TSTFileS.44: For RecCnt := 1 to MaxRecs do
      cs:0093 C70650010100   mov    Word ptr [TSTFileS.RECCNT],00
        ***  Clear the loop counter For first loop
      cs:0099 EB04           jmp    TSTFileS.46 (009F)
        ***  Jump to the start of the Loop
      cs:009B FF065001       inc    Word ptr [TSTFileS.RECCNT]
        ***  The Loop returns to here to inC the loop counter
    TSTFileS.46:  FillRec (RecCnt);
      cs:009F A15001         mov    ax,[TSTFileS.RECCNT]
        ***  Move our RecCnt Var into AX register
      cs:00A2 31D2           xor    dx,dx
        ***  Clear the DX Register
      cs:00A4 52             push   dx
      cs:00A5 50             push   ax
        ***  Push the DX and AX Registers on the stack.  Remember our
             FillRec Routine expects a LongInt to be passed and RecCnt
             is only a Word.  So it Pushes the DX as the 0 Upper Word
             of the LongInt.
      cs:00A6 0E             push   cs
        ***  Push the code segment For some reasion.
      cs:00A7 E856FF         call   TSTFileS.FILLREC
        ***  Call our FillRec Routine
    TSTFileS.48:  Write (MyTypedFile , Rec);
      cs:00AA BF4400         mov    di,0044
      cs:00AD 1E             push   ds
      cs:00AE 57             push   di
        ***  These instructions push the address of MyTypedFile Record
             on the stack.  The first paramiter
      cs:00AF BF4401         mov    di,0144
      cs:00B2 1E             push   ds
      cs:00B3 57             push   di
        ***  These instructions push the address of Rec Record
             on the stack.  The second paramiter
      cs:00B4 9AAA05262D     call   2D26:05AA
        ***  Call the System Function to Write a Typed File.  (In next msg)
      cs:00B9 83C404         add    sp,0004
        ***  Remove our passed parameters from the stack
    TSTFileS.51:  FillRec (RecCnt + $FFFF);
      cs:00BC A15001         mov    ax,[TSTFileS.RECCNT]
      cs:00BF 05FFFF         add    ax,FFFF
      cs:00C2 31D2           xor    dx,dx
      cs:00C4 52             push   dx
      cs:00C5 50             push   ax
      cs:00C6 0E             push   cs
      cs:00C7 E836FF         call   TSTFileS.FILLREC
        ***  Now heres a NASTY littel bug With the code!!!  Look at the
             above routine.  We wanted to pass a LongInt $FFFF + rec cnt
             But we wound up adding the $FFFF to a Word then passing a
             LongInt.  if you Compile the sample pas File you'll be able
             to see this bug in action..  Good reasion to use a Debugger.
    TSTFileS.55:  BlockWrite (MyUnTypedFile, Rec, Sizeof (MyRec))
      cs:00CA BFC400         mov    di,00C4
      cs:00CD 1E             push   ds
      cs:00CE 57             push   di
        ***  These instructions push the address of MyUnTypeFile Record
             on the stack.  The First paramiter
      cs:00CF BF4401         mov    di,0144
      cs:00D2 1E             push   ds
      cs:00D3 57             push   di
      cs:0594 26817D02B3D7   cmp    es:Word ptr [di+02],D7B3
        *** Armed With the address of the File Record in ES:DI
            Check the File mode For a In/Out operation.  See Dos
            Unit Constant definitions.
      cs:059A 7406           je     05A2
        *** if that Compare was equal then jump to return
      cs:059C C7063C006700   mov    Word ptr [SYSTEM.inOUTRES],0069
        *** if we didn't jump then put File not oopen For output in
            Ioresult.
      cs:05A2 C3             ret
        *** Go back to where we were called
      cs:05A3 B43F           mov    ah,3F
      cs:05A5 BA6400         mov    dx,0064
      cs:05A8 EB05           jmp    05AF

        *** The Write instruction entered the system Unit here
      cs:05AA B440           mov    ah,40
        *** Load Dos Function in AH
      cs:05AC BA6500         mov    dx,0065
        *** Default error code 101 disk Write error load in DX
      cs:05AF 55             push   bp
        ***  Save the BP register
      cs:05B0 8BEC           mov    bp,sp
        *** Load the BP Register With the stack Pointer
      cs:05B2 C47E0A         les    di,[bp+0A]
        *** Load Address of MyTypeFile Rec in ES:SI
      cs:05B5 E8DCFF         call   0594
        *** Call check For File mode.  See top of message
      cs:05B8 751B           jne    05D5
        *** if error jump out of this
      cs:05BA 1E             push   ds
      cs:05BB 52             push   dx
        *** Save These Registers as we'er going to use them
      cs:05BC C55606         lds    dx,[bp+06]
        *** Load the address of our Rec in DS:DX Registers
      cs:05BF 268B4D04       mov    cx,es:[di+04]
        *** Look up Record structure For a File Rec and you'll see
            that RecSize is Byte # 4.  Move that value to CX
      cs:05C3 268B1D         mov    bx,es:[di]
        *** First Byte of a File Rec is the Handel.  Move into BX
      cs:05C6 CD21           int    21
        *** Make the Dos CALL to Write.  AH = 40
                                         BX = File Handel
                                         CX = # of Bytes to Write.
                                         DS:DX = Address of Buffer
            Returns Error In AX if Carry flag set or
            if good CF = 0 number of Bytes written in AX
      cs:05C8 5A             pop    dx
      cs:05C9 1F             pop    ds
        *** Restore the Registers
      cs:05CA 7206           jb     05D2
        *** Jump if there was an error (if Carry flag Set)
      cs:05CC 3BC1           cmp    ax,cx
        *** Comp Bytes requested to what was written
      cs:05CE 7405           je     05D5
        *** if equal then jump out we'r just about done
      cs:05D0 8BC2           mov    ax,dx
        *** Move default errorcode 101 to AX
      cs:05D2 A33C00         mov    [SYSTEM.inOUTRES],ax <--Set Ioresult
        *** Store 101 to Ioresult
      cs:05D5 5D             pop    bp
        *** Restore BP register
      cs:05D6 CA0400         retf   0004
        *** We'r out of here

      cs:05D9 B33F           mov    bl,3F
      cs:05DB B96400         mov    cx,0064
      cs:05DE EB05           jmp    05E5

        *** The BlockWrite instruction entered the system Unit here
      cs:05E0 B340           mov    bl,40
        *** Move Dos Function in BL
      cs:05E2 B96500         mov    cx,0065
        *** Default error 101 Write error in CX
      cs:05E5 55             push   bp
        *** Save BP Register
      cs:05E6 8BEC           mov    bp,sp
        *** Move Stack Pointer to BP
      cs:05E8 C47E10         les    di,[bp+10]
        *** Load Address of MyUnTypedFile Record in ES:DI
      cs:05EB E8A6FF         call   0594
        *** Check For Open in Write Mode See top of message
      cs:05EE 753F           jne    062F
        *** Jump if not in Write mode
      cs:05F0 8B460A         mov    ax,[bp+0A] ]
        *** Move File Record cnt in to ax
      cs:05F3 0BC0           or     ax,ax
        *** Check For 0 Record request
      cs:05F5 741C           je     0613
        *** Jump if 0 rec requested
      cs:05F7 1E             push   ds
      cs:05F8 51             push   cx
        *** Save them we'er going to use them
      cs:05F9 26F76504       mul    es:Word ptr [di+04]
        *** Multiply Record size With RecCnt in AX result in DX & AX
      cs:05FD 8BC8           mov    cx,ax

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