Assembly 正在尝试获取当前正在运行的.COM程序的名称。它存放在哪里?
我正在尝试获取当前正在运行的.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字符串。 要获取当前运行的.
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
你不能通过解析得到它吗?(只要您没有修改
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中解决问题的内容。