问题描述
我正在尝试获取当前运行的 .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