home *** CD-ROM | disk | FTP | other *** search
- { 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