在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
关键修复点说明
- 修正文件路径:将
filename改为虚拟盘根路径'C:\inventory.txt',匹配emu8086的虚拟驱动器结构。 - 正确处理输入缓冲区:读取输入后,从缓冲区第3字节(
+2偏移)复制用户输入的字符,并添加$结束符。 - 添加错误检查:在文件创建、打开、读写操作后检查CF标志位,处理失败情况。
- 准确判断EOF:使用
read_from_file返回的AX值(读取的字节数)判断文件是否结束。 - 打印时动态定位字段:通过查找
$结束符来定位每个字段的起始位置,避免固定偏移导致的越界问题。
内容的提问来源于stack exchange,提问作者avery grace
相关产品推荐
相关产品推荐

