Полный путь к себе в исполняемом файле DOS - PullRequest
0 голосов
/ 01 декабря 2018

В моей 16-битной DOS-программе я хочу получить полный путь к экземпляру моей программы, используя прерывание DOS или его внутренние таблицы.Другими словами, я ищу эквивалент DOS функции Windows API GetModuleFileName (NULL)

Прерывание 21h / AH = 60h показалосьбыть правильной дорожкой, но она терпит неудачу, когда программа не находится в текущем каталоге.Я сделал простую тестовую программу:

MYTEST PROGRAM FORMAT=COM
    MOV AH,60h    ; TRUENAME - CANONICALIZE FILENAME OR PATH.
    MOV SI,MyName
    MOV DI,MyFullName
    INT 21h       ; Convert filename DS:SI to canonizalized name in ES:DI.
    MOV AH,09h    ; WRITE STRING$ TO STARNDARD OUTPUT.
    MOV DX,DI
    INT 21h       ; Display the canonizalized name.
    RET           ; Terminate program.
MyName     DB "MYTEST.COM",0 ; The ASCIIZ name of self (this executable program).
MyFullName DB 256 * BYTE '$' ; Room for the canonizalized name, $-terminated.
  ENDPROGRAM MYTEST

Он был создан как "C: \ WORK \ MYTEST.COM" и запущен в DOSBox на Windows 10 / 64bits:

C:\WORK>dir
MYTEST   COM     284 Bytes.
C:\WORK>mytest
C:\WORK\MYTEST.COM      REM this works as expected.
C:\WORK>d:
D:\>c:mytest
D:\MYTEST.COM           REM this is wrong, no such file exists.
D:\>

Кто-нибудь знает способ получить argv [0] в 16-битной ассемблерной программе?

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

Вы можете получить эту информацию, взглянув на среду DOS.

PSP вашей программы содержит, помимо прочего - по смещению 002Ch - адрес сегмента среды DOS.Среда заполнена связкой строк ASCIIZ и оканчивается дополнительным нулем.

Тогда наступит бессмысленное?слово, которое вы должны пропустить.

Здесь и далее вы можете найти полный путь к вашей запущенной программе.

0 голосов
/ 01 декабря 2018

В зависимости от версии DOS вы можете использовать недокументированный факт, что имя файла можно найти после переменных среды.Например:

org 100h

    mov ax, [2Ch]    ; segment of environment from PSP
    mov ds, ax
    xor si, si
findloop:
    cmp word [si], 0 ; one zero for end of string, another for end of table
    lea si, [si+1]
    jne findloop
    lodsb            ; skip end of table
    lodsw            ; number of additional strings (?)
    cmp ax, 1
    jne error
    mov ah, 2
printloop:
    lodsb
    test al, al
    jz done
    mov dl, al
    int 21h
    jmp printloop
done:
error:
    mov ax, 4C00h
    int 21h

По крайней мере в DOSBox это дает полный путь.В разных ОС вам может потребоваться объединиться с текущим каталогом или даже выполнить поиск PATH, если он вообще работает.

...