Contributor: SWAG SUPPORT TEAM { 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