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