在我的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”,并在Windows 10 / 64bits的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]的方法吗?
答案 0 :(得分:3)
您可以通过查看DOS环境来获取此信息。
您的程序的PSP除其他外-偏移量002Ch-DOS环境的段地址。环境中填充了一堆ASCIIZ字符串,并以附加的零终止。
那么就变得毫无意义了吗?您必须跳过的单词。
此后,您可以找到正在运行的程序的完整路径规范。
答案 1 :(得分:2)
根据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
(如果可以的话)。