汇编程序无法打开文件

Assembler can't open file

组装好MINI-44.asm后,我尝试运行MINI-44.com_。然后显示"unable to open file"。然后我将 MyBuild 中的所有文件复制到 MySource 和 vdrive\c 以防万一。但它要么没有找到任何文件,要么无法打开文件。我该如何解决这个问题?

;#MAKE_EXE#
.model small
.code
FNAME equ 9EH
ORG 100H
START:
MOV AH,4EH;
MOV DX,OFFSET COM_FILE;
INT 21H;
SEARCH_LOOP:
JC DONE;
MOV AX,3D01H;
MOV DX,FNAME; 
INT 21H;
XCHG AX,BX;
MOV AH,40H;
MOV CL,42H;
MOV DX,100H;
INT 21H;
MOV AH,3EH;
INT 21H;
MOV AH,4FH;
INT 21H;
JMP SEARCH_LOOP;
DONE:
RET;
;COM_FILE DB 'C:\EMU8086\vdrive\C\*.com_',0;
;COM_FILE DB 'C:\EMU8086\MyBuild\*.com_',0;
COM_FILE DB '\MySource\*.com',0;
;COM_FILE DB '\vdrive\C\*.com_',0;
;COM_FILE DB '\MySource\*.com_',0;
;COM_FILE DB 'C:\EMU8086\MySource\*.com_',0;
END START;

除了 Michael Petch 和 Peter Cordes 的评论中已经提到的内容:

您不应使用固定地址 (9Eh),而应使用文件名标签。

如果修改代码,地址将不再正确。使用标签可以解决这个问题。

9Eh不能是正确的地址,因为.com文件从地址100h开始,所以[=中的所有地址12=] 文件必须至少为 100h.

不确定地址 9Eh 中的内容(它是地址 space 内为命令行保留的地址;但是,如果命令行参数不使用此地址小于 ~20 字节长)。但是,显然9Eh处存储的数据不是文件名!

所以很明显你会得到一个 "file not found" 错误,因为 dx 寄存器包含 9Eh 但地址 9Eh 没有有效的文件名。

要编译成 .COM 文件,您只需要:

.model tiny
ORG 100h

DOS.SearchFirst函数需要CX参数。为了搜索任何普通文件指定 CX=0:

 mov ah, 4Eh
 xor cx, cx
 mov dx, offset COM_FILE
 int 21h
 jc  Done

将此 ASCIIZ 文件规范与通配符一起使用:

COM_FILE db 'C:\EMU8086\MyBuild\*.com', 0

由于默认的 DTA(磁盘传输区)是 80h,所以你说得对:FNAME equ 9EH
如果 DOS 找到任何匹配的文件,其 ASCIIZ 文件名将位于地址 9Eh。

如果更改了 DTA 地址(通常这是您通过 function 1Ah) you need to use the other address. You can always retrieve the current DTA address via function 2Fh 自己完成的操作)。结果将在 ES:BX.

I have installed emu8086 on C:\emu8086 and all the COM files I want to open is on C:\emu8086\MyBuild. Assembly files is in C:\emu8086\MySource. Now which one is the correct path?

如果您仍然无法打开该文件,可能是因为一方面您在 s p e c i f i c 目录 (C:\emu8086\MyBuild) 中搜索了它,但另一方面你试着在 c ur r e n t 目录 (???).
中打开它 解决方案是将 DOS 给您的文件名附加到用于请求文件的同一路径:

 mov si, FNAME
 mov di, FileName
More:
 lodsb
 stosb
 cmp al, 0      ;Copy includes the terminating zero
 jnz More
 mov dx, Path
 mov ax, 3D01h  ;Access write-only
 int 21h
 jc  OpenFileError
 mov bx, ax     ;Handle

使用这些数据定义:

COM_FILE db 'C:\EMU8086\MyBuild\*.com', 0
Path     db 'C:\EMU8086\MyBuild\'
FileName db '.............'

MOV AX,3D01H;
MOV DX,FNAME; 
INT 21H;

如果无法打开文件,DOS returns CF 设置。请检查这个!


MOV AH,40H;
MOV CL,42H;
MOV DX,100H;
INT 21H;

.写入会失败。检查CF!
.size参数是CX不只是CL


DONE:
RET

尽管这在此处有效(具有完整堆栈的 .COM 程序),但您应该养成使用正确程序终止代码的习惯:

mov ax, 4C00h
int 21h