【问题标题】:I can't open the file for reading through the program. Assembler我无法打开文件以通过程序进行阅读。汇编器
【发布时间】:2021-06-11 12:08:26
【问题描述】:

通过 TASM 广播时,一切正常,正在创建扩展名为 .COM 的文件.但是当我运行这个程序时,会弹出一条消息说文件没有打开。 必须使用扩展名为 .COM 的执行程序。

请帮我解决这个问题。下面是汇编语言程序的代码。该程序从与可执行程序位于同一文件夹中的文本文件中读取。


.model tiny

.code

    ORG 100h

BEGIN:

main    proc
        ;clearing the screen
        call    ClearScreen
        ;opening a file
        mov     ah,     3Dh     ;File Open
        mov     al,     00h     ;Read Only
        lea     dx,     FileName
        mov     cx,     01h
        int     21h
        jnc     @@ShowText
        mov     ah,     09h     ;displays an error message about opening a file
        lea     dx,     msgErrorFileOpen
        int     21h
        jmp     @@Exit
@@ShowText:
        mov     FileHandle,     ax      ;saving the file descriptor
 
        ;reading from a file
        mov     ah,     3Fh     ;File Read
        mov     bx,     FileHandle
        lea     dx,     FileBuffer
        mov     cx,     FileBufferSize
        int     21h
        jnc     @@Process
        mov     ah,     09h     ;output of a file read error message
        lea     dx,     msgErrorFileRead
        int     21h
        jmp     @@CloseFile
@@Process:
        mov     FileBufLen,     ax      ;the actual number of bytes read from the file
 
        ;preparing the screen buffer - filling it with symbol+attribute pairs (color)
        mov     cx,     ax      ;the actual number of bytes read from the file
        lea     si,     FileBuffer
        lea     di,     ScreenBuffer
        push    ds
        pop     es
        cld
        @@NextChar:
                lodsb
                call    GetAttr
                stosw
        loop    @@NextChar
        ;buffer output to the screen
        mov     ah,     13h
        mov     al,     03      ;string format: char, attr, char, attr...; move the cursor
        lea     bp,     ds:ScreenBuffer ;es:bp - string address
        push    ds
        pop     es
        mov     cx,     FileBufLen      ;string length (only characters are counted)
        mov     bh,     0       ;video page
        mov     dh,     0       ;output start line
        mov     dl,     0       ;output start column
        int     10h
 
        ;closing the file
@@CloseFile:
        mov     ah,     3Eh
        mov     bx,     FileHandle
        int     21h
 
        mov     ah,     09h
        lea     dx,     msgPressAnyKey
        int     21h
 
@@Exit:
        ;end of the program
        mov ah, 00h
        int 16h     ;waiting for the key to close the program
        
        int     20h
main    endp
 
;Clearing the screen
ClearScreen     proc
        push    ax
        push    bx
        push    cx
        push    dx
 
        mov     ah,     06h     ;SCROLL UP function
        mov     bh,     07h     ;attribute to fill in
        mov     cx,     0000h   ;upper-left corner of the window
        mov     dx,     184fh   ;lower right corner of the window
        int     10h
 
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
ClearScreen     endp
 
;Getting the color of a symbol by its belonging to a group
;blue - if the character is a punctuation mark
;red - if the character is a digit
;white - in all other cases
;at the input
;al-character
;on the output
;al-character
;ah - color of the symbol
GetAttr proc
        ;assigning the "default" attribute"
        mov     ah,     clWhite
        ;checking the character for belonging to the "numbers group"
        cmp     al,     '0'
        jb      @@IsPunctuation
        cmp     al,     '9'
        ja      @@IsPunctuation
        mov     ah,     clRed
        ret
        ;checking the character for belonging to the "punctuation marks group"
@@IsPunctuation:
        pushf
        push    si
        push    di
        push    cx
        push    es
 
        push    ds
        pop     es
        lea     di,     Punctuation
        mov     cx,     LenPunctuation
        cld
        repne   scasb
        jnz     @@Skip
        mov     ah,     clBlue
@@Skip:
        pop     es
        pop     cx
        pop     di
        pop     si
        popf

        ret
GetAttr endp

    BufSize                         equ     80*25
    clBlue                          equ     01h
    clRed                           equ     04h
    clWhite                         equ     07h

    FileName                        db      'Screen.txt', 0
    FileHandle                      dw      ?
    FileBuffer                      db      BufSize dup(?)
    FileBufferSize                  dw      $-FileBuffer
    FileBufLen                      dw      ?               ;the number of bytes actually read

    align 2
    ScreenBuffer                    db      2*BufSize dup(?)
    ScreenBufferSize                dw      $-ScreenBuffer

    ;program messages
    CrLf                            db      0Dh, 0Ah, '$'
    msgPressAnyKey                  db      0Dh, 0Ah, 'Press any key to exit...', '$'
    msgErrorFileOpen                db      'File open error.', '$'
    msgErrorFileRead                db      'File read error.', '$'
    msgMouseFault                   db      'The mouse or mouse driver was not detected.', 13, 10, '$'

    Punctuation                     db      '.,!?;:"()', "'"
    LenPunctuation                  dw      $-Punctuation

end     BEGIN

【问题讨论】:

  • 你是如何准确地运行程序的?您可能需要从可执行文件所在的同一目录中运行它。

标签: assembly x86-16 tasm


【解决方案1】:

正如迈克尔所说,文件 ".\Screen.txt" 可能在当前目录中找不到。尝试用完整路径重新定义它。

我对@9​​87654321@ 的定义有疑问, 我不得不把它改成 LenPunctuation EQU $-Punctuation 使您的程序正常工作。最好(不仅在 TASM 中)使用方括号 [] 来区分从内存加载 (mov cx [LenPunctuation']) 和加载 asm 时间常数 (mov cx, LenPunctuation)。

当 COM 程序启动时,所有的段寄存器都被预定义为相同的值,所有这些对

push ds
pop es

可以省略。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    • 2017-08-12
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    相关资源
    最近更新 更多