从文件ASM 8086的中间读取

时间:2021-12-08 13:50:51

I am trying to read data from the middle of a file.

我试图从文件中间读取数据。

I used int 21h, ah = 3fh, but it's read the file from his beginning.

我使用int 21h,啊= 3fh,但它从头开始读取文件。

Is there a way to read data not from the beginning of the file?

有没有办法从文件的开头读取数据?

(ASM 8086, i am using TASM if it relevance)

(ASM 8086,如果相关,我正在使用TASM)

3 个解决方案

#1


Yes, you can use int 21h function 42h - Move file pointer, after opening the file.

是的,您可以使用int 21h功能42h - 打开文件后移动文件指针。

mov     ah,42h          ;function
mov     al,0            ;to calculate offset from beginning of file
mov     bx,handle       ;from opening the file
mov     cx,yyyy         ;most significant part of offset
mov     dx,xxxx         ;least significant part of offset
int     21h             ;system call
jc      error           ;check if errro

The next read from the file will start at this location.

文件的下一次读取将从此位置开始。

Values for al

al的值

0 = offset from beginning of file
1 = offset from current position (cx:dx is signed)
2 = offset from end of file (ditto)

I suggest you find the documentation now I have given you the tip.

我建议你现在找到我给你提示的文件。

#2


Next is a little full program to do what you want to achieve : it opens the file, jump to a middle position (byte 500), read something, and close the file. Here it is, made with EMU8086:

接下来是一个完整的程序来完成你想要实现的目标:它打开文件,跳转到中间位置(字节500),读取内容,然后关闭文件。在这里,用EMU8086制作:

.model small

.stack 100h

.data

filename    db 'tree_img.png',0
filehandler dw ?
buffer      db 10 dup (?)

.code
start:

;INITIALIZE DATA SEGMENT.
  mov  ax, @data
  mov  ds, ax                 

  call read_middle                     ;<==============

;WAIT FOR ANY KEY.    
  mov  ah, 7
  int  21h

;FINISH PROGRAM.
  mov  ax, 4c00h
  int  21h

;-----------------------------------------

read_middle proc

;OPEN FILE.
  mov  ah, 3dh          ;SERVICE TO OPEN FILE.
  mov  al, 0            ;OPEN AS READ ONLY.
  lea  dx, filename           
  int  21h  
  mov  filehandler, ax  ;NECESSARY FOR OPERATIONS ON FILE.

;JUMP TO POSITION INSIDE THE FILE.                            <==============
  mov  ah, 42h          ;SERVICE FOR SEEK.
  mov  al, 0            ;START FROM THE BEGINNING OF FILE.
  mov  bx, filehandler  ;FILE.
  mov  cx, 0            ;THE FILE POSITION MUST BE PLACED IN
  mov  dx, 500          ;CX:DX, EXAMPLE, TO JUMP TO POSITION
  int  21h              ;14000000 SET CX:DX = D5:9F80.

;READ ONE CHAR FROM CURRENT FILE POSITION.
  mov  ah, 3fh          ;SERVICE TO READ FROM FILE.
  mov  bx, filehandler
  mov  cx, 1            ;HOW MANY BYTES TO READ.
  lea  dx, buffer       ;WHERE TO STORE THE READ BYTES.  
  int  21h

;CLOSE FILE.
  mov  ah, 3eh          ;SERVICE TO CLOSE FILE.
  mov  bx, filehandler  
  int  21h

  ret
read_middle endp

;-----------------------------------------

end start

#3


For to get the length of the file in DI:SI

为了获得DI中的文件长度:SI

xor     cx, cx               ;  set high                              
xor     dx, dx               ;  set low
mov     ax, 4202h            ; Get length of file from end
int   21h
jc  ERROR
mov     si, ax               ; return low
mov     di, dx               ; return high
xor     cx, cx               ;  set high
xor     dx, dx               ;  set low
mov     ax, 4200h            ; Set file pointer to the start position
int   21h
jc  ERROR

RBIL->inter61b.zip->INTERRUP.F
http://www.cs.cmu.edu/~ralf/files.html

--------D-2142-------------------------------
INT 21 - DOS 2+ - "LSEEK" - SET CURRENT FILE POSITION
AH = 42h
AL = origin of move
  00h start of file
  01h current file position
  02h end of file
BX = file handle
CX:DX = (signed) offset from origin of new file position
Return: CF clear if successful
DX:AX = new file position in bytes from start of file
CF set on error
AX = error code (01h,06h) (see #01680 at AH=59h/BX=0000h)
Notes:  for origins 01h and 02h, the pointer may be positioned before the
  start of the file; no error is returned in that case (except under
  Windows NT), but subsequent attempts at I/O will produce errors
  if the new position is beyond the current end of file, the file will
  be extended by the next write (see AH=40h); for FAT32 drives, the
  file must have been opened with AX=6C00h with the "extended size"
  flag in order to expand the file beyond 2GB
BUG: using this method to grow a file from zero bytes to a very large size
     can corrupt the FAT in some versions of DOS; the file should first be
     grown from zero to one byte and then to the desired large size
SeeAlso: AH=24h,INT 2F/AX=1228h

#1


Yes, you can use int 21h function 42h - Move file pointer, after opening the file.

是的,您可以使用int 21h功能42h - 打开文件后移动文件指针。

mov     ah,42h          ;function
mov     al,0            ;to calculate offset from beginning of file
mov     bx,handle       ;from opening the file
mov     cx,yyyy         ;most significant part of offset
mov     dx,xxxx         ;least significant part of offset
int     21h             ;system call
jc      error           ;check if errro

The next read from the file will start at this location.

文件的下一次读取将从此位置开始。

Values for al

al的值

0 = offset from beginning of file
1 = offset from current position (cx:dx is signed)
2 = offset from end of file (ditto)

I suggest you find the documentation now I have given you the tip.

我建议你现在找到我给你提示的文件。

#2


Next is a little full program to do what you want to achieve : it opens the file, jump to a middle position (byte 500), read something, and close the file. Here it is, made with EMU8086:

接下来是一个完整的程序来完成你想要实现的目标:它打开文件,跳转到中间位置(字节500),读取内容,然后关闭文件。在这里,用EMU8086制作:

.model small

.stack 100h

.data

filename    db 'tree_img.png',0
filehandler dw ?
buffer      db 10 dup (?)

.code
start:

;INITIALIZE DATA SEGMENT.
  mov  ax, @data
  mov  ds, ax                 

  call read_middle                     ;<==============

;WAIT FOR ANY KEY.    
  mov  ah, 7
  int  21h

;FINISH PROGRAM.
  mov  ax, 4c00h
  int  21h

;-----------------------------------------

read_middle proc

;OPEN FILE.
  mov  ah, 3dh          ;SERVICE TO OPEN FILE.
  mov  al, 0            ;OPEN AS READ ONLY.
  lea  dx, filename           
  int  21h  
  mov  filehandler, ax  ;NECESSARY FOR OPERATIONS ON FILE.

;JUMP TO POSITION INSIDE THE FILE.                            <==============
  mov  ah, 42h          ;SERVICE FOR SEEK.
  mov  al, 0            ;START FROM THE BEGINNING OF FILE.
  mov  bx, filehandler  ;FILE.
  mov  cx, 0            ;THE FILE POSITION MUST BE PLACED IN
  mov  dx, 500          ;CX:DX, EXAMPLE, TO JUMP TO POSITION
  int  21h              ;14000000 SET CX:DX = D5:9F80.

;READ ONE CHAR FROM CURRENT FILE POSITION.
  mov  ah, 3fh          ;SERVICE TO READ FROM FILE.
  mov  bx, filehandler
  mov  cx, 1            ;HOW MANY BYTES TO READ.
  lea  dx, buffer       ;WHERE TO STORE THE READ BYTES.  
  int  21h

;CLOSE FILE.
  mov  ah, 3eh          ;SERVICE TO CLOSE FILE.
  mov  bx, filehandler  
  int  21h

  ret
read_middle endp

;-----------------------------------------

end start

#3


For to get the length of the file in DI:SI

为了获得DI中的文件长度:SI

xor     cx, cx               ;  set high                              
xor     dx, dx               ;  set low
mov     ax, 4202h            ; Get length of file from end
int   21h
jc  ERROR
mov     si, ax               ; return low
mov     di, dx               ; return high
xor     cx, cx               ;  set high
xor     dx, dx               ;  set low
mov     ax, 4200h            ; Set file pointer to the start position
int   21h
jc  ERROR

RBIL->inter61b.zip->INTERRUP.F
http://www.cs.cmu.edu/~ralf/files.html

--------D-2142-------------------------------
INT 21 - DOS 2+ - "LSEEK" - SET CURRENT FILE POSITION
AH = 42h
AL = origin of move
  00h start of file
  01h current file position
  02h end of file
BX = file handle
CX:DX = (signed) offset from origin of new file position
Return: CF clear if successful
DX:AX = new file position in bytes from start of file
CF set on error
AX = error code (01h,06h) (see #01680 at AH=59h/BX=0000h)
Notes:  for origins 01h and 02h, the pointer may be positioned before the
  start of the file; no error is returned in that case (except under
  Windows NT), but subsequent attempts at I/O will produce errors
  if the new position is beyond the current end of file, the file will
  be extended by the next write (see AH=40h); for FAT32 drives, the
  file must have been opened with AX=6C00h with the "extended size"
  flag in order to expand the file beyond 2GB
BUG: using this method to grow a file from zero bytes to a very large size
     can corrupt the FAT in some versions of DOS; the file should first be
     grown from zero to one byte and then to the desired large size
SeeAlso: AH=24h,INT 2F/AX=1228h