You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TASM汇编程序无法正常读取文本文件,启动后直接退出求排查

Let's break down why your program exits immediately and fix the issues step by step:

1. Critical: File Opening Failure with No Feedback

The most likely reason your program exits right away is that it can't locate the_message.txt—either the file doesn't exist in the same directory as your executable, or there's a path mismatch. When DOS interrupt int 21h function 3Dh (open file) fails, it sets the carry flag (CF), and your code jumps straight to exit without any error message. You have no way to tell this is happening!

2. Unnecessary (and Risky) lds Instructions

You're using lds dx, point_fname and lds dx, point_buffer to load pointers, but this is redundant and could break your data segment (DS) setup. Since you already set DS to your .data segment with mov ax,@data / mov ds,ax, you can directly use mov dx, offset filename and mov dx, offset string to get the correct offsets in the data segment.

3. Flawed Input Selection Logic

In the ask section, after checking if input is 1 (ASCII 31h), you immediately jump to decrypt2 for any other input. This means if the user enters 2 (the intended decrypt option) or any random character, it will try to run the decrypt2 routine, which will fail if count isn't 2, leading to a confusing experience.

4. Unintended Flow in Error Cases

Your notAllowed section has a commented-out jmp exit, which means after showing the error, the program will fall through to exit anyway. It's better to let the user try again instead of exiting abruptly.


Fixed Code

Here's the corrected version with all issues addressed:

JUMPS
.model small
.data
handle dw 0
filename db 'the_message.txt',0
string db 200 dup (" ")
errorMes db 0ah,0dh,'Error: File operation failed!','$'
invalidInput db 0ah,0dh,'Invalid input! Type 1 or 2.','$'
mes db 0ah,0dh,'Type 1 to crypt, type 2 to decrypt!','$'
mes1 db 0ah,0dh,'Crypted one time ','$'
mes2 db 0ah,0dh,'Crypted two times ','$'
mes3 db 0ah,0dh,'Decrypted','$'
count db 0
.stack 256
.code
main:
    mov ax,@data
    mov ds,ax

    ; Open file (read-only mode)
    mov al,0
    mov dx,offset filename
    mov ah,3dh
    int 21h
    jc file_error   ; Show error if open fails
    mov [handle],ax

    ; Read up to 200 bytes from file
    mov bx,[handle]
    mov cx,200
    mov dx,offset string
    mov ah,3fh
    int 21h
    jc file_error
    mov bp,ax       ; Store number of bytes actually read

    ; Close file
    mov ah,3eh
    int 21h
    jc file_error

ask:
    ; Show operation prompt
    mov ah,09h
    lea dx,mes
    int 21h

    ; Get user input (echoed to screen)
    mov ah,01h
    int 21h

    ; Validate input
    cmp al,31h      ; Check for '1' (crypt)
    je crypt1
    cmp al,32h      ; Check for '2' (decrypt)
    je decrypt_branch
    ; Handle invalid input
    mov ah,09h
    lea dx,invalidInput
    int 21h
    jmp ask

crypt1:
    cmp count,0
    jg crypt2
    ; Perform first encryption (add 1 to each byte)
    mov cx,bp
    mov si,0
go1:
    add string[si],1
    inc si
    loop go1
    inc count
    ; Show status message
    mov ah,09h
    lea dx,mes1
    int 21h
    jmp show

crypt2:
    cmp count,1
    jg notAllowed
    ; Perform second encryption (add 2 to each byte)
    mov cx,bp
    mov si,0
go2:
    add string[si],2
    inc si
    loop go2
    inc count
    ; Show status message
    mov ah,09h
    lea dx,mes2
    int 21h
    jmp show

decrypt_branch:
    ; Route decrypt request based on current encryption count
    cmp count,2
    je decrypt2
    cmp count,1
    je decrypt1
    jmp notAllowed

decrypt2:
    ; Reverse second encryption (subtract 2 from each byte)
    mov cx,bp
    mov si,0
goDecr2:
    sub string[si],2
    inc si
    loop goDecr2
    dec count
    ; Show status message
    mov ah,09h
    lea dx,mes3
    int 21h
    jmp show

decrypt1:
    ; Reverse first encryption (subtract 1 from each byte)
    mov cx,bp
    mov si,0
goDecr1:
    sub string[si],1
    inc si
    loop goDecr1
    dec count
    ; Show status message
    mov ah,09h
    lea dx,mes3
    int 21h
    jmp show

show:
    ; Display modified string to screen
    mov cx,bp
    mov si,0
show_loop:
    mov ah,02h
    mov dl,string[si]
    int 21h
    inc si
    loop show_loop
    ; Add new line after output
    mov ah,02h
    mov dl,0ah
    int 21h
    mov dl,0dh
    int 21h
    jmp ask         ; Return to prompt for more operations

notAllowed:
    ; Show invalid operation error
    mov ah,09h
    lea dx,errorMes
    int 21h
    jmp ask         ; Let user try again

file_error:
    ; Show file operation failure error
    mov ah,09h
    lea dx,errorMes
    int 21h
    jmp exit

exit:
    ; Terminate program
    mov ax,4c00h
    int 21h
end main

Key Fixes Explained:

  • Added file error feedback: If any file operation fails, it shows a clear message before exiting.
  • Removed redundant lds instructions to keep DS correctly pointed to the data segment.
  • Fixed input validation: Now it properly checks for both 1 and 2, and loops back to the prompt for invalid inputs.
  • Added a decrypt_branch to route decrypt requests based on the current encryption count.
  • Made the show routine loop back to the prompt, so users can perform multiple encryption/decryption cycles.
  • Explicit jumps in error cases to avoid unintended program flow.

内容的提问来源于stack exchange,提问作者S. Werner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:32:24