Full path to self in DOS executable
Asked Answered
I

2

6

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?

Ironsides answered 1/12, 2018 at 12:37 Comment(1)
Note that argv[0] and “Full path to self in DOS executable” are different things. I'm not sure how to get either though.Tubb
V
5

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.

Vesper answered 1/12, 2018 at 14:50 Comment(1)
Yes, it works both in EXE and COM formats, thank you.Ironsides
R
3

You can obtain this info from looking at the DOS environment.

The PSP of your program contains amongst other things - at offset 002Ch - the segment address of the DOS environment. The environment is filled with a bunch of ASCIIZ strings and terminated by an additional zero.

Then comes a meaningless? word that you must skip.

Hereafter you can find the full pathspec to your running program.

Righthander answered 1/12, 2018 at 14:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.