Ассемблер не может открыть файл - PullRequest
2 голосов
/ 11 мая 2019

После сборки MINI-44.asm я попытался запустить MINI-44.com_. Затем он показал «не удалось открыть файл». Затем я скопировал все файлы в 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;

Ответы [ 2 ]

2 голосов
/ 16 мая 2019

Для компиляции в файл .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 (Область пересылки диска) составляет 80 часов, вы можете сказать: FNAME equ 9EH.
Если DOS обнаружит какой-либо соответствующий файл, его имя файла ASCIIZ будет по адресу 9Eh.

Если, однако, адрес DTA был изменен (обычно это то, что вы сделали бы самостоятельно с помощью функция 1Ah ), вам нужно использовать другой адрес. Вы всегда можете получить текущий адрес DTA с помощью функции 2Fh . Результат будет в ES:BX.

Я установил emu8086 на C: \ emu8086, и все COM-файлы, которые я хочу открыть, находятся на C: \ emu8086 \ MyBuild. Файлы сборки находятся в C: \ emu8086 \ MySource. Теперь какой путь правильный?

Если вы все еще не можете открыть файл, возможно, это связано с тем, что, с одной стороны, вы искали его в директории * (C:\emu8086\MyBuild), а с другой стороны, вы пытаетесь открыть его в текущий каталог (???).
Решение состоит в том, чтобы добавить имя файла, которое 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 возвращает набор CF. Проверьте это!


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

. Написание может потерпеть неудачу. Проверьте CF!
Параметр размера CX, а не CL.


DONE:
RET

Хотя это работает здесь (программа .COM с неповрежденным стеком), вы должны использовать для правильного кода завершения программы:

mov ax, 4C00h
int 21h
0 голосов
/ 11 мая 2019

В дополнение к вещам, уже упомянутым в комментариях Майкла Петча и Питера Кордеса:

Не следует использовать фиксированный адрес (9Eh), но метку для имени файла.

Если вы измените код, адрес больше не будет правильным.Это можно исправить с помощью метки.

И 9Eh не может быть правильным адресом, поскольку файл .com начинается с адреса 100h, поэтому все адреса внутри файла .comдолжно быть не менее 100h.

Неясно, что находится по адресу 9Eh (это адрес внутри адресного пространства, зарезервированного для командной строки; однако этот адрес не используется, еслидлина аргументов командной строки составляет менее ~ 20 байтОднако очевидно, что данные, хранящиеся в 9Eh, не являются именами файлов!

Таким образом, ясно, что вы получите ошибку «файл не найден», поскольку регистр dx содержит 9Eh, нонедопустимое имя файла по адресу 9Eh.

...