正在尝试获取当前 运行 .COM 程序的名称。它存储在哪里?

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

我正在尝试获取当前 运行 .COM 文件的名称。

我知道 int 21h 函数 4Eh (SearchForFirstMatch) 和 4Fh (SearchForNextMatch) 会将名称放在 DiskTransferArea DTA 的偏移量 1Eh 处,但这是当前 运行 .COM 文件的名称也在 DTA 中?如果没有,如何获取?

编辑:可能应该提到我正在使用 TASM

DOS 环境是一系列 ASCIIZ 字符串,以多一个零加上某种晦涩的单词结尾。此后您将当前 运行ning 程序的名称作为 ASCIIZ 字符串。
要获取当前 运行ning .COM 文件的名称,请使用下一个代码:

  .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

我在DOSBox 0.74中测试程序,结果没问题。

[编辑 1]

从评论中我看到问题尚未解决,即使您也是 运行 DOSBox 中的代码。我建议您使用可以在 https://flatassembler.net 下载的 FASM 汇编程序。它是最简单的汇编程序,并且是一步编译器,这意味着不需要单独的链接。
这是我们当前程序的改编来源:

  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)

在 FASM 中(就像在 NASM 中一样),mov dx, Buffer 给出 Buffer 变量的(偏移)地址,而 mov dx, [Buffer]给出存储在 Buffer 变量中的值。如果您来自 MASM 或 TASM,这是最重要的区别之一。

FASM 生成的可执行文件将有 306 个字节。

[编辑 2]

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

指令 mov ax, word ptr [002Ch] 没有执行我们需要的操作。
在 TASM 中,方括号的存在,甚至 word ptr 的提及都不会将其变成从内存中读取。它被编码为 AX (B8,2C,00) 的立即加载。
对于我们的程序,这意味着我们将查看中断向量中偏移量 02C0h 处存储的许多零 Table。

可行的备选方案包括(都需要 5 个字节):

  • 使用寄存器寻址内存

      mov bx, 002Ch          ; BB,2C,00
      mov ds, [bx]           ; 8E,1F
    
  • 使用(冗余)段覆盖地址内存

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

在以下位置阅读有关此特殊 TASM 语法的更多信息: Confusing brackets in MASM32