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

6
在我的16位DOS程序中,我希望使用DOS中断或其内部表获取到程序实例的完整路径。 换句话说,我正在寻找Windows API函数GetModuleFileName(NULL)的DOS等效函数。
中断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",并在Windows 10/64位的DOSBox上运行:
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]的方法吗?


请注意,argv [0]和“DOS可执行文件中的完整路径”是不同的东西。 我不确定如何获取任何一个。 - fuz
2个回答

5

根据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(如果有用的话)。


是的,它可以在EXE和COM格式中都运行,谢谢。 - vitsoft

3

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

您的程序的PSP包含了许多内容,其中包括偏移量002Ch处的DOS环境段地址。该环境填充着一堆ASCIIZ字符串,并以额外的零终止。

然后是一个无意义的单词,您必须跳过它。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接