簡體   English   中英

如何使用 16 位 DOS 調用從文件中掃描符號

[英]How to scan symbols from file with 16-bit DOS calls

我的任務是計算用戶輸入其名稱的.txt文件中有多少個字符,並在需要時編輯字符。 我是 Assembly x86 的新手,所以我需要一些文件讀取和文件符號讀取方面的幫助。

正如下面的代碼所示,我使用int 21,3d打開文件並使用int 21,3f讀取文件。 但是我不明白如何正確地從文件中讀取符號,因為如果我的 txt 文件中有 100 個隨機符號,如何一個一個地讀取並全部計數?

我的代碼:

.data
fname_input db 255,?,255 dup("$")
buff db 255,?,255 dup("$")
endl     db 13,10,"$"
handle dw ?

.code
start:

    mov dx, @data
    mov ds, dx

    mov ah, 0Ah
    mov dx, offset fname_input ;input put in to buffer
    int 21h
    
    mov ah, 3fh 
    mov al, 00 ;only read
    mov dx, offset fname_input ; name of the file to open
    int 21h
    
    mov ah,3fh 
    mov bx,[handle]
    mov cx,4             
    mov dx,offset buff
    int 21h
    
    mov ax, 4c00h ;exit
    int 21h 

end start

對代碼的更正。

 mov ah, 3fh mov al, 00;only read mov dx, offset fname_input; name of the file to open int 21h mov ah,3fh mov bx,[handle] mov cx,4 mov dx,offset buff int 21h
  • 這可能是一個錯字,但 DOS.OpenFile function 是 3Dh(所以不是 3fh)
  • 文件名不在offset fname_input的地址。 那是您為 DOS.BufferedInput function 0Ah 定義的輸入結構。
    實際文件名在 memory 中開始高 2 個字節,現在由代碼 13 終止。您必須將此代碼更改為 0,然后才能將其呈現給 DOS.OpenFile function。
  • 您絕不能忽略對 DOS 報告的任何錯誤的檢查!
  • 您的 DOS.ReadFile function 3Fh 甚至在初始化之前就使用了句柄變量!

解決任務的方法

最簡單的( 1 )解決方案將一次讀取文件一個字節,直到讀取 function 報告它無法滿足請求。 這將發生在文件的末尾。
對於您收到的每個字節,您可以增加一個計數器來確定文件長度,如果您發現字節需要更改,那么您可以將文件指針設置為 position 並將新的字符代碼寫入文件。 因為您不僅需要對文件的讀訪問權限,而且在打開文件時還必須向 DOS 請求讀/寫訪問權限

    mov  si, offset TheInput
    mov  dx, si
    mov  ah, 0Ah                 ; DOS.BufferedInput
    int  21h
    xor  bx, bx
    mov  bl, [si + 1]            ; Length of the filename
    mov  [si + 2 + bx], bh       ; Changing carriage return 13 into zero-terminator 0

    lea  dx, [si + 2]            ; Filename
    mov  ah, 3D02h               ; DOS.OpenFile for read/write
    int  21h                     ; -> AX CF
    jc   ERROR
    mov  [handle], ax

MainLoop:
    mov  dx, offset TheBuffer
    mov  cx, 1
    mov  bx, [handle]
    mov  ah, 3Fh                 ; DOS.ReadFile
    int  21h                     ; -> AX CF
    jc   ERROR
    cmp  ax, cx
    jb   EOF

    ...

    jmp  MainLoop

EOF:
    mov  bx, [handle]
    mov  ah, 3Eh                 ; DOS.CloseFile
    int  21h                     ; -> AX CF
    
    mov  ax, 4C00h               ; DOS.Terminate
    int  21h 

在上述代碼片段中的省略號處,您可以對收到的那個字節做任何您需要做的事情。
為了設置文件指針一個 position 以便您可以使用您在TheBuffer中准備的新字符更新文件,您需要使用 DOS.MoveFilepointer function 42h。 CX:DX中使用 -1 的 32 位偏移量。

    mov  dx, -1
    mov  cx, -1
    mov  bx, [handle]
    mov  ah, 4201h               ; DOS.MoveFilepointer from current position
    int  21h                     ; -> DX:AX CF
    jc   ERROR

    mov  dx, offset TheBuffer
    mov  cx, 1
    mov  bx, [handle]
    mov  ah, 40h                 ; DOS.WriteFile
    int  21h                     ; -> AX CF
    jc   ERROR

( 1 ) 一次讀取超過 1 個字節的解決方案將更有效,盡管涉及更多。 在這種情況下,最好定義一個 512 字節的緩沖區。 它與磁盤扇區大小和 DOS 很好地維護的緩沖區相匹配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM