In my 16bit DOS program I want to get the full path to the instance of my program, using DOS interrupt or its internal tables. In other words, I'm looking for DOS equivalent of Windows API function GetModuleFileName(NULL)
Interrupt 21h/AH=60h seemed to be a right track but it fails when the program is not in current directory. I made a simple test program:
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
It was created as "C:\WORK\MYTEST.COM" and run in DOSBox on 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:\>
Does anybody know a way how to get argv[0] in 16bit assembler program?
Depending on DOS version you might use the undocumented fact that the file name can be found after the environment variables. Such as:
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
At least in dosbox this gives the full path. Under different OS you might need to combine with the current directory or even search PATH
, if it works at all.