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
 

AltStyle によって変換されたページ (->オリジナル) /