假设我有 PROGRAM.ASM - 我在数据段中有以下内容:
.data
Filename db 'file.txt', 0
Fhndl dw ?
Buffer db ?
我想我想'file.txt'是动态的?编译后,PROGRAM.exe 需要能够通过命令行接受文件名:
c:\> PROGRAM anotherfile.txt
EXECUTION GOES HERE
如何启用此功能?先感谢您。
DOS 将命令行存储在称为程序段前缀(“PSP”)的遗留结构中。我的意思是legacy。这种结构被设计为向后兼容从 CP/M 移植的程序。
PSP在哪里?
您知道构建为.COM
文件的程序总是以 开头ORG 100h
吗?其原因恰恰是 - 对于 .COM 程序 - PSP 始终存储在代码段的开头(在 CS:0h)。PSP 的长度为 0FFh 字节,实际的程序代码在此之后立即开始(即在 CS:100h 处)。
该地址也可以在 DS:00h 和 ES:00h 方便地获得,因为 .COM 格式的关键特征是所有段寄存器都以相同的值开始(并且 COM 程序通常不会更改它们)。
要从.COM
程序中读取命令行,您可以选择其长度为 CS:80h(或 DS:80h 等,只要您没有更改这些寄存器)。命令行从 CS:81h 开始并占用 PSP 的其余部分,以回车 (0Dh) 作为终止符结束,因此命令行的长度永远不会超过 126 个字节。
(这就是为什么命令行在 DOS 中永远是 126 字节的原因,尽管我们多年来都希望它可以更长。由于 WinNT 使用提供了一种不同的机制来访问命令行,WinNT/XP/etc.命令行不受此大小限制的影响)。
对于.EXE
程序,您不能依赖 CS:00h,因为启动代码段几乎可以位于内存中的任何位置。但是,当程序启动时,DOS 总是将 PSP 存储在默认数据段的基础上。因此,在启动时,对于 .EXE 和 .COM 程序,DS:00h 和 ES:00h 将始终指向 PSP。
如果您在程序开始时没有跟踪 PSP 地址,并且您更改了 DS 和 ES,您可以随时要求 DOS 提供段值,通过 INT 21h,函数 62h。PSP 地址的段部分将在 BX 中返回(偏移量当然是 0h)。