assembly 我怎么能读一个文件,一个字符一个字符,直到它达到'|在8086年?

ix0qys7i  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(142)

我想一个接一个地读这些字符,当读到"|”的性格。我用的是dosbox和8086。

MOV AX, @DATA
    MOV DS, AX
    lea si, buffer
    ; Open the file for reading
    MOV AH, 3Dh         ; Open existing file
    mov al,0
    LEA DX, FileName    ; Load address of file name
    XOR CX, CX          ; Access mode (CX = 0, read-only)
    INT 21h
    MOV fhandle, AX          ; Store file handle

Read_Loop:
    ; Read data from the file
    MOV AH, 3Fh         ; Read from file
    MOV CX, 1           ; Read 1 byte at a time
    LEA DX, Buffer[si+2]      ; Load address of data buffer
    mov bx,fhandle
    INT 21h
    
    ;call NEW_LINE
    ;mov dl,[Buffer]
    ;mov ah,02h 
    ;int 21h
    
    mov cl,'3'
    cmp cl,Buffer[si+2]
    je File_End
    inc si
    jmp Read_Loop
    
    
File_End:

    ;mov ah,09h
    ;lea dx, data2
    ;int 21h
    
    ; Close the file
    MOV AH, 3Eh         ; Close file
    MOV BX, fhandle          ; Use the file handle
    INT 21h

    MOV AH, 4Ch         ; Exit program
    INT 21h
vuktfyat

vuktfyat1#

使用DOS.ReadFile函数3Fh是正确的,但您似乎将其与DOS.BufferedInput function 0Ah的工作方式混淆了!

lea si, buffer
LEA DX, Buffer[si+2] ; Load address of data buffer

由于lea si, buffer指令已经将数据缓冲区的地址加载到SI寄存器中,因此由于您第二次添加了 Buffer,接下来的LEA DX, Buffer[si+2] ; Load address of data buffer指令将使地址加倍。看到+2,我怀疑你是混淆了其他DOS功能。总之,在DS:DX中传递的指针将毫无意义!

mov cl,'3'
cmp cl,Buffer[si+2]

如果你的意图是在到达"|'字符,那你为什么要和'3'字符比较?

XOR CX, CX          ; Access mode (CX = 0, read-only)

DOS.OpenFile函数3Dh完全不依赖于CX!您可以在AL寄存器的最低3位中指定只读状态。

我想一个一个读,读到"|”的性格。

接下来是完成此任务的最小示例。您必须始终考虑操作(尤其是文件操作)可能失败的可能性。您需要检查DOS提供的进位标志以及其他信息,如实际读取的字符数。

mov dx, OFFSET FileName  ; Load address of file name
  mov ax, 3D00h            ; DOS.OpenFile for reading
  int 21h                  ; -> AX CF
  jc  Abort
  mov bx, ax               ; CONST Store file handle
  mov cx, 1                ; CONST Read 1 byte at a time
  mov si, OFFSET Buffer

Read_Loop:
  mov dx, si
  mov ah, 3Fh              ; DOS.ReadFile
  int 21h                  ; -> AX CF
  jc  Close
  cmp ax, cx
  jne Close
  mov al, [si]
  inc si
  cmp al, '|'
  jne Read_Loop

Close:
  mov ah, 3Eh              ; DOS.CloseFile
  int 21h

  ... Do something useful with the string

Abort:
  mov ax, 4C00h            ; DOS.Terminate
  int 21h

您不希望数据缓冲区溢出

即使DOS操作工作正常,它仍然可能发生的文件,你读不包含终止'|“字符,或者直到"|'字符的长度比数据缓冲区的长度高上级。对于这些情况,您需要决定是否将其视为错误或可以截断结果。在下面的重写中,我展示了后者(这里假设有一个大约30字节的缓冲区):

mov dx, OFFSET FileName  ; Load address of file name
  mov ax, 3D00h            ; DOS.OpenFile for reading
  int 21h                  ; -> AX CF
  jc  Abort
  mov bx, ax               ; CONST Store file handle
  mov cx, 1                ; CONST Read 1 byte at a time
  mov si, OFFSET Buffer

Read_Loop:
  mov dx, si
  mov ah, 3Fh              ; DOS.ReadFile
  int 21h                  ; -> AX CF
  jc  Close
  cmp ax, cx
  jne Close
  mov al, [si]
  inc si
  cmp al, '|'
  je  Close
  cmp si, OFFSET Buffer + 30 - 1
  jb  Read_Loop
  mov BYTE PTR [si], '|'   ; (*)

Close:
  mov ah, 3Eh              ; DOS.CloseFile
  int 21h

  ... Do something useful with the string

Abort:
  mov ax, 4C00h            ; DOS.Terminate
  int 21h

(*)处理器,以便任何进一步的处理只需要处理“|'终止的字符串。

相关问题