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

在emu8086中创建写入文件遇路径错误的技术求助

问题分析与修复方案

核心问题梳理

1. 文件路径错误

emu8086的vdrive\C目录模拟的是DOS环境下的C:\根目录,代码中使用的'C:\emu8086\vdrive\C\inventory.txt'是真实系统路径,而非虚拟盘路径,导致系统无法找到虚拟盘中的目标文件。

2. 输入缓冲区读取错误

使用DOS中断0Ah读取用户输入时,缓冲区结构为:

  • 第1字节:最大输入长度
  • 第2字节:实际输入字符数
  • 第3字节起:用户输入的字符
    但原代码直接复制整个缓冲区(包括前两个控制字节)到文件,写入的并非真实输入内容。

3. 打印缺少字符串结束符

DOS中断09h打印字符串需要以$结尾,原代码未给用户输入添加该结束符,导致打印时出现乱码或读取随机数据。

4. 文件操作无错误检查

创建、读写文件后未检查返回值,无法及时发现操作失败的情况。

5. EOF判断逻辑错误

read_from_file过程未正确返回读取的字节数,导致无法准确判断文件是否结束。


修复后的完整代码

.model small
.stack 100h
.data
    ; 输入缓冲区结构:[最大长度][实际长度][输入字符]
    manufacturer  db 20          ; 最大输入长度
                 db 0           ; 实际输入长度(由0Ah自动填充)
                 db 20 dup(0)   ; 输入字符缓冲区

    model        db 20
                 db 0
                 db 20 dup(0)

    color        db 20
                 db 0
                 db 20 dup(0)

    engine_size  db 10           ; 引擎尺寸缓冲区
                 db 0
                 db 10 dup(0)

    doors        db 2
                 db 0
                 db 2 dup(0)

    filename      db 'C:\inventory.txt', 0  ; 虚拟盘正确路径
    continue_buffer db 2, 0, 2 dup(0)  ; Y/N输入缓冲区

    prompt_msg1   db 'Enter manufacturer: $'  
    prompt_msg2   db 'Enter model: $'    
    prompt_msg3   db 'Enter color: $'  
    prompt_msg4   db 'Enter engine size: $' 
    prompt_msg5   db 'Enter number of doors: $' 
    continue_prompt db 'Add more inventory (Y/N)? $'

    newline       db 0Dh, 0Ah, '$'    ; 换行符
    done_msg      db '*** Awesome Auto Lot Inventory file has been processed ***', 0Dh, 0Ah, '$'    
    
    ; 文件读写相关变量
    file_handle dw ?
    bytes_written dw ?
    read_buffer db 72 dup(0)  ; 预留空间存放结束符

.code
main:   
; 初始化数据段
    mov ax, @data
    mov ds, ax     
    
; 创建文件
mov ah, 3Ch   ; DOS创建文件功能
lea dx, filename   
mov cx, 0     ; 文件属性:普通文件
int 21h
jc create_fail ; CF置位表示创建失败
mov file_handle, ax ; 保存文件句柄 
    
; 主循环
main_loop:   
    call get_auto_info   ; 获取车辆信息
    call write_to_file

    ; 询问是否继续添加
    lea dx, continue_prompt
    mov ah, 09h
    int 21h

    ; 获取Y/N输入
    lea dx, continue_buffer
    mov ah, 0Ah
    int 21h

    ; 检查是否输入N
    mov al, continue_buffer + 2  
    cmp al, 'N'
    je close_file       
    
    lea dx, newline  
    mov ah,09h
    int 21h
    
    jmp main_loop  
    
create_fail:
    lea dx, newline
    mov ah,09h
    int 21h
    db 'Failed to create file!$'
    jmp exit_prog
    
close_file:
    ; 关闭文件
    mov ah, 3Eh
    mov bx, file_handle
    int 21h

    lea dx, done_msg    
    mov ah, 09h
    int 21h  
    
    ; 打开文件读取
    mov ah, 3Dh           
    lea dx, filename
    mov al, 0            ; 只读模式
    int 21h
    jc open_fail ; 检查打开是否失败
    mov file_handle, ax   
    
 read_loop:
    call read_from_file      
    cmp ax, 0                ; 读取字节数为0表示EOF
    je done_reading          
    
    ; 打印读取的信息
    call print_auto_info 
    
    jmp read_loop  
    
open_fail:
    lea dx, newline
    mov ah,09h
    int 21h
    db 'Failed to open file!$'
    jmp exit_prog
    
done_reading:
; 关闭文件
mov ah, 3Eh
mov bx, file_handle
int 21h    
    
exit_prog:
    mov ah, 4Ch
    int 21h   
    

; 获取车辆信息过程
get_auto_info proc
    ; 输入制造商
    lea dx, prompt_msg1
    mov ah, 09h
    int 21h

    lea dx, manufacturer
    mov ah, 0Ah
    int 21h

    ; 添加字符串结束符
    mov cl, manufacturer+1
    mov ch, 0
    mov si, cx
    mov manufacturer[si+2], '$'

    lea dx, newline
    mov ah, 09h
    int 21h

    ; 输入型号
    lea dx, prompt_msg2
    mov ah, 09h
    int 21h

    lea dx, model
    mov ah, 0Ah
    int 21h

    mov cl, model+1
    mov ch, 0
    mov si, cx
    mov model[si+2], '$'

    lea dx, newline
    mov ah, 09h
    int 21h

    ; 输入颜色
    lea dx, prompt_msg3
    mov ah, 09h
    int 21h

    lea dx, color
    mov ah, 0Ah
    int 21h

    mov cl, color+1
    mov ch, 0
    mov si, cx
    mov color[si+2], '$'

    lea dx, newline
    mov ah, 09h
    int 21h

    ; 输入引擎尺寸
    lea dx, prompt_msg4
    mov ah, 09h
    int 21h

    lea dx, engine_size
    mov ah, 0Ah
    int 21h

    mov cl, engine_size+1
    mov ch, 0
    mov si, cx
    mov engine_size[si+2], '$'

    lea dx, newline
    mov ah, 09h
    int 21h

    ; 输入车门数量
    lea dx, prompt_msg5
    mov ah, 09h
    int 21h

    lea dx, doors
    mov ah, 0Ah
    int 21h

    mov cl, doors+1
    mov ch, 0
    mov si, cx
    mov doors[si+2], '$'

    lea dx, newline
    mov ah, 09h
    int 21h

    ret
get_auto_info endp   

; 写入车辆信息到文件
write_to_file proc
    ; 复制制造商信息(跳过前两个控制字节)
    lea si, manufacturer + 2  
    lea di, read_buffer   
    mov cl, manufacturer + 1
    mov ch, 0
    rep movsb             
    mov byte ptr [di], '$' ; 添加结束符
    inc di

    ; 复制型号信息
    lea si, model + 2         
    mov cl, model + 1
    mov ch, 0
    rep movsb
    mov byte ptr [di], '$'
    inc di

    ; 复制颜色信息
    lea si, color + 2         
    mov cl, color + 1
    mov ch, 0
    rep movsb
    mov byte ptr [di], '$'
    inc di

    ; 复制引擎尺寸信息
    lea si, engine_size + 2   
    mov cl, engine_size + 1
    mov ch, 0
    rep movsb
    mov byte ptr [di], '$'
    inc di

    ; 复制车门数量信息
    lea si, doors + 2         
    mov cl, doors + 1
    mov ch, 0
    rep movsb
    mov byte ptr [di], '$'
    inc di

    ; 计算总写入字节数
    mov ax, di
    sub ax, read_buffer

    ; 写入文件
    mov ah, 40h           
    mov bx, file_handle   
    lea dx, read_buffer   
    mov cx, ax            
    int 21h               
    jc write_fail
    mov bytes_written, ax  

    ret
write_fail:
    lea dx, newline
    mov ah,09h
    int 21h
    db 'Failed to write to file!$'
    jmp exit_prog
write_to_file endp

; 从文件读取信息
read_from_file proc  
    mov ah, 3Fh                   
    mov bx, file_handle          
    lea dx, read_buffer           
    mov cx, 72                    
    int 21h
    jc read_fail
    ret
read_fail:
    lea dx, newline
    mov ah,09h
    int 21h
    db 'Failed to read from file!$'
    jmp exit_prog
read_from_file endp

; 打印车辆信息
print_auto_info proc
    ; 打印制造商
    lea dx, read_buffer           
    mov ah, 09h
    int 21h
    lea dx, newline
    mov ah, 09h
    int 21h

    ; 定位到型号(跳过制造商字符串)
    lea si, read_buffer
find_model:
    cmp byte ptr [si], '$'
    je found_model
    inc si
    jmp find_model
found_model:
    inc si ; 跳过$
    lea dx, si
    mov ah, 09h
    int 21h
    lea dx, newline
    mov ah, 09h
    int 21h

    ; 定位到颜色
find_color:
    cmp byte ptr [si], '$'
    je found_color
    inc si
    jmp find_color
found_color:
    inc si
    lea dx, si
    mov ah, 09h
    int 21h
    lea dx, newline
    mov ah, 09h
    int 21h

    ; 定位到引擎尺寸
find_engine:
    cmp byte ptr [si], '$'
    je found_engine
    inc si
    jmp find_engine
found_engine:
    inc si
    lea dx, si
    mov ah, 09h
    int 21h
    lea dx, newline
    mov ah, 09h
    int 21h

    ; 定位到车门数量
find_doors:
    cmp byte ptr [si], '$'
    je found_doors
    inc si
    jmp find_doors
found_doors:
    inc si
    lea dx, si
    mov ah, 09h
    int 21h
    lea dx, newline
    mov ah, 09h
    int 21h
    
    ret
print_auto_info endp

end main                

关键修复点说明

  1. 修正文件路径:将filename改为虚拟盘根路径'C:\inventory.txt',匹配emu8086的虚拟驱动器结构。
  2. 正确处理输入缓冲区:读取输入后,从缓冲区第3字节(+2偏移)复制用户输入的字符,并添加$结束符。
  3. 添加错误检查:在文件创建、打开、读写操作后检查CF标志位,处理失败情况。
  4. 准确判断EOF:使用read_from_file返回的AX值(读取的字节数)判断文件是否结束。
  5. 打印时动态定位字段:通过查找$结束符来定位每个字段的起始位置,避免固定偏移导致的越界问题。

内容的提问来源于stack exchange,提问作者avery grace

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 09:12:02