DOS 可执行文件中自身的完整路径

Full path to self in DOS executable

在我的 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

它在 Windows 10/64 位的 DOSBox 中创建为 "C:\WORK\MYTEST.COM" 和 运行:

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:\>

有人知道如何在 16 位汇编程序中获取 argv[0] 的方法吗?

根据 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 中这给出了完整路径。在不同的 OS 下,您可能需要结合当前目录甚至搜索 PATH,如果它有效的话。

您可以通过查看 DOS 环境获得此信息。

您程序的 PSP 在偏移量 002Ch 处包含 DOS 环境的段地址等内容。环境中充满了一堆 ASCIIZ 字符串,并以一个额外的零结尾。

然后来个无意义的?您必须跳过的单词。

此后您可以找到 运行 程序的完整路径规范。