DOS开发中如何获取当前运行的.COM程序文件名?TASM适配场景
DOS场景下获取运行中.COM程序文件名的常见误区与实现方案
核心疑问澄清:当前运行的.COM程序文件名是否存在于DTA区域?
结论是不会主动存储在初始DTA的对应位置。
你掌握的int 21h 4Eh/4Fh功能将搜索匹配到的文件名写入DTA 1Eh偏移的机制完全正确,但这个位置存放的是你主动发起搜索操作后匹配到的文件条目。DOS加载.COM程序时,默认将DTA缓冲区设置在PSP(程序段前缀)00h偏移的起始位置,这块缓冲区在程序启动时只是预留的内存空间,其中1Eh偏移位置的内容是加载流程残留的无效值,DOS从不会预先把当前运行程序的自身文件名写入这里,直接读这个位置得到的结果没有任何参考意义。
适配TASM开发环境的可靠获取方案
方案1:读取PSP内置FCB存储的启动文件名
DOS解析启动命令行时,会自动把用户输入的可执行文件名参数构造成两个未打开的FCB(文件控制块),分别放在PSP的005Ch和006Ch偏移位置。
- 结构对应:FCB偏移08h起始处为8字节主文件名,后续3字节为扩展名,长度不足的位置用空格填充
- 优势:.COM程序刚启动时DS寄存器直接指向PSP段,不需要额外内存操作就能快速读取文件名
- 局限:只能拿到用户敲命令时输入的文件名本身,不带盘符、路径信息,无法区分不同目录下的同名程序
方案2:读取环境块存储的完整带路径文件名
DOS 2.0以上版本加载程序时,会在环境变量块的末尾存储程序启动时使用的完整带盘符、路径的可执行文件名,这是最可靠的获取实际运行文件路径的方案,实现流程如下:
- 从PSP偏移2Ch位置读取环境变量块的段地址——.COM程序启动时DS本来就指向PSP段,这个值可以直接从当前段的偏移位置读出来
- 遍历环境块内容:所有环境变量都是以0结尾的字符串,遍历到连续两个0字节的位置,就到达了环境块的结尾
- 跳过连续两个0字节、以及紧随其后的2字节0值保留字后,遇到的第一个以0结尾的字符串,就是当前运行程序的完整文件名
TASM下.COM程序的核心实现代码片段:
org 100h start: ; 读取PSP偏移2Ch处的环境块段地址 mov ax, [2Ch] mov es, ax xor si, si scan_env_loop: ; 逐字节检测连续两个0的结束标记 cmp byte ptr es:[si], 0 jnz move_next cmp byte ptr es:[si+1], 0 jz env_tail_found move_next: inc si jmp scan_env_loop env_tail_found: add si, 4 ; 跳过双0结束标记+保留字段 ; 此时es:si就是指向完整0结尾文件名的指针,可按需做后续处理
方案注意事项
如果硬要沿用DTA的搜索逻辑实现获取,也可以先从PSP的FCB里拿到文件名,再手动调用4Eh功能在当前目录搜索匹配文件,把结果写到自定义DTA的1Eh偏移位置,但这个方案可靠性很差:只要当前工作目录下有和你程序同名的其他文件,搜出来的条目根本不是你正在运行的程序本体,远不如直接读环境块的方案靠谱。
内容的提问来源于stack exchange,提问作者AndrewHoover898
相关产品推荐
相关产品推荐

