Search code examples
assemblydosx86-16tasm

Trying to get the name of the currently running .COM program. Where is it stored?


I'm trying to get the name of the currently running .COM file.

I know that int 21h functions 4Eh (SearchForFirstMatch) and 4Fh (SearchForNextMatch) will put the name at offset 1Eh in the DiskTransferArea DTA, but is the name of the currently running .COM file also in the DTA? If not, how can I get it?

EDIT: Probably should have mentioned that I'm using TASM


Solution

  • The DOS environment is a series of ASCIIZ strings and ending with one more zero plus an obscure word of some kind. Hereafter you have the name of the currently running program as an ASCIIZ string.
    To get the name of the currently running .COM file use next code:

      .model tiny
      .code
    
      ORG 256
    
    Begin:
      mov ax, word ptr [002Ch]  ; Segment of the DOS environment DOES NOT WORK IN TASM
      mov ds, ax                ;                                SEE [EDIT 2]
      xor si, si
      cld
      jmp StartSearch
    SkipEntry:
      lodsb
      cmp al, 0
      jne SkipEntry
    StartSearch:
      lodsb
      cmp al, 0
      jne SkipEntry         ; Go skip an environment string
      ; End of environment
      lodsw            ; ???
    
      ;Here `DS:SI` points at the name of the running program (path included).
    
      ; Copy
      mov di, offset Buffer
    Again:
      movsb
      cmp byte ptr [si], 0
      jne Again
      ; Restoring DS
      push es
      pop  ds
      mov byte ptr [di], "$"
      ; Printing path
      mov dx, offset Buffer
      mov ah, 09h
      int 21h
      ; Wait key and end
      mov ah, 00h
      int 16h
      mov ax, 4C00h
      int 21h
    
    Buffer db 256 dup (0)
    
      END Begin
    

    I tested the program in DOSBox 0.74 and results are OK.

    [edit 1]

    From comments I see that the issue is not yet resolved even though, you too, run the code in DOSBox. I suggest you use the FASM assembler that you can download at https://flatassembler.net. It's the easiest assembler around and it's a one-step compiler, meaning there's no separate linking required.
    This is the adapted source for our current program:

      ORG 256          ; FASM automatically 'knows' that you want a .COM program
                       ; No '.model' or so needed
    Begin:
      mov ds, [002Ch]  ; Segment of the DOS environment
      xor si, si
      cld
      jmp StartSearch
    SkipEntry:
      lodsb
      cmp al, 0
      jne SkipEntry
    StartSearch:
      lodsb
      cmp al, 0
      jne SkipEntry    ; Go skip an environment string
      ; End of environment
      lodsw            ; ???
    
      ;Here `DS:SI` points at the name of the running program (path included).
    
      ; Copy
      mov di, Buffer
    Again:
      movsb
      cmp byte [si], 0
      jne Again
      ; Restoring DS
      push es
      pop  ds
      mov byte [di], "$"
      ; Printing path
      mov dx, Buffer
      mov ah, 09h
      int 21h
      ; Wait key and end
      mov ah, 00h
      int 16h
      mov ax, 4C00h
      int 21h
    
    Buffer db 256 dup (0)
    

    In FASM (just like in NASM), mov dx, Buffer gives the (offset) address of the Buffer variable, whereas mov dx, [Buffer] gives the value stored IN the Buffer variable. This is one of most important differences if you're coming from MASM or TASM.

    The executable that FASM produces will have 306 bytes.

    [edit 2]

    mov ax, word ptr [002Ch]
    mov ds, ax
    

    The instruction mov ax, word ptr [002Ch] does not do what we needed.
    In TASM, neither the presence of the square brackets, nor even the mention of word ptr turn this into a read from memory. It gets encoded as an immediate load to AX (B8,2C,00).
    For our program it means that we will be looking at the many zeroes stored at offset 02C0h in the Interrupt Vector Table.

    Working alternatives include (both require 5 bytes):

    • Using a register addresses memory

        mov bx, 002Ch          ; BB,2C,00
        mov ds, [bx]           ; 8E,1F
      
    • Using a (redundant) segment override addresses memory

        mov ds, cs:[002Ch]      ; 2E,8E,1E,2C,00
      

    Read more about this peculiar TASM syntax in: Confusing brackets in MASM32