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

Assembly 正在尝试获取当前正在运行的.COM程序的名称。它存放在哪里?,assembly,dos,x86-16,tasm,Assembly,Dos,X86 16,Tasm,我正在尝试获取当前正在运行的.COM文件的名称 我知道int 21h函数4Eh(SearchForFirstMatch)和4Fh(SearchForNextMatch)将把名称放在DiskTransferArea DTA的偏移量1Eh处,但是当前运行的.COM文件的名称也在DTA中吗?如果没有,我怎样才能得到它 编辑:可能应该提到我使用的是TASM,DOS环境是一系列ASCIIZ字符串,最后是一个零加上某种模糊的单词。此后,您将当前正在运行的程序的名称作为ASCIIZ字符串。 要获取当前运行的.

我正在尝试获取当前正在运行的.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中运行代码。我建议您使用可以在下载的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
给出缓冲变量的(偏移量)地址,而
mov-dx,[Buffer]
给出存储在缓冲变量中的值。如果您来自MASM或TASM,这是最重要的区别之一

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

[编辑2]

指令
mov-ax,word ptr[002Ch]
不能满足我们的需要。
在TASM中,无论是方括号的存在,还是提及
单词ptr
都不能将其转化为从内存读取。它被编码为立即加载到
AX
(B8,2C,00)。
对于我们的程序,这意味着我们将查看中断向量表中存储在偏移量02C0h处的许多零

工作备选方案包括(两者都需要5个字节):

  • 使用寄存器寻址内存

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

      mov bx, 002Ch          ; BB,2C,00
      mov ds, [bx]           ; 8E,1F
    
      mov ds, cs:[002Ch]      ; 2E,8E,1E,2C,00
    
有关此特殊TASM语法的更多信息,请参阅:

你不能通过解析得到它吗?(只要您没有修改
DS
,它应该位于
DS:0000h
)。PSP有以程序名IIRC开头的命令行。它位于最后一个变量后面的环境块中,该块通过读取PSP:2Ch中的段字来定位。这是
ds:4493
而不是
4493:0000
现在您只需要滚动环境变量。这取决于您使用的汇编程序。也许您必须使用
movds[0x002C]
。也许您需要
.model-tiny
指令和
.code
结束
。使用您以前使用的任何东西生成.COM文件。如果汇编程序对
mov-ds[002Ch]
非常挑剔,请添加
word-ptr
,或者您可以将其拆分为
mov-ax,word-ptr[002Ch]
mov-ds,ax
。只是一个想法。
SI=3
意味着环境是空的。很好,但如果在filespec中找不到任何可读文本,则DOS实现是错误的。或者非常旧,比如版本1或版本2。操作
DS
没有危险,只要我们在事后恢复它。好吧,我只是在DOSBox 0.74中验证了环境,一切正常。每一点信息都存在。@andrewhoover 898我终于在TASM中破解了这个程序的问题。在我编辑的答案中,阅读有关TASM/MASM中解决问题的内容。