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

问题描述

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

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

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

解决方法

DOS 环境是一系列 ASCIIZ 字符串,并以一个多零加上某种晦涩的单词结尾。此后,您将获得当前运行程序的名称作为 ASCIIZ 字符串。
要获取当前运行的 .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,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],Buffer
  mov ah,4C00h
  int 21h

Buffer db 256 dup (0)

在 FASM 中(就像在 NASM 中一样),mov dx,Buffer 给出了 Buffer 变量的(偏移)地址,而 mov dx,[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 处的许多零。

可行的替代方案包括(均需要 5 个字节):

  • 使用寄存器寻址内存

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

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

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...