我正在写我的第一个TSR。我知道我必须使用INT 21H的功能31H。当我查看它时,我发现DX中的值是段落中的"内存大小"。我不知道如何计算,GOOGLE也没有帮助。我想知道如何计算代码段落中的内存大小。
我刚刚找到了这个
mov dx, OFFSET Install ; DX = bytes in resident section
mov cl, 4
shr dx, cl ; Convert to number of paragraphs
inc dx ; plus one
mov ax, 3100h ; Request Function 31h, error code=0
int 21h ; Terminate-and-stay-resident
为什么有加号?并知道我应该假设一个段落=偏移* 16,那就是它?
答案 0 :(得分:2)
段落是16字节的内存增量。在程序运行时动态计算程序大小将部分取决于编程语言,程序模型和使用的段结构。通常,您要做的是安排链接映射,在整个程序映像的末尾放置一个几乎为空(可能是1字节分配)的段。单个未使用但已分配的字节将给出一个可在运行时引用的符号。
因为,当在16位环境中编程时,段地址在段落边界上递增,计算程序运行时间大小的过程是从“段”中减去我们的程序段加载时间PSP(程序段前缀) “上面提到的未使用的字节变量的部分地址。不同的是当你去TSR时要求DOS保持加载的段落数。
请注意,在构建程序时仔细研究链接器生成的映射文件非常有用。至少你需要检查你在图像末尾设置的标记段确实是图像中的最后一个。
另请注意,某些编程环境可能已经在其编程模板中为此目的设置了标记段。
答案 1 :(得分:2)
在您的示例中,标签Install
指代流程中TSR驻留部分的末尾。通过获取标签,右移四位并递增结果,可以有效地除以16(段落的大小)并加1以确保考虑到部分最后一段。
在一种情况下,此计算过于悲观:如果标签Install
位于段落边界上,则您的示例将分配比需要多的一个段落,该段落未使用。要对此进行改进,请改为执行以下操作:
mov dx, offset Install
add dx, 15
mov cl, 4
shr dx, cl
mov ax, 3100h
int 21h
(请注意,其编码比您的原始编码略大。)
另一个问题是计算可以在构建时而不是在运行时完成。对于mov
\ shr
组合在86-DOS程序中相当普遍这一事实表明,这对于大多数程序来说太过神秘。根据汇编器的不同,可能需要一些棘手的处理。这是一个不同问题的答案,并为NASM编写了一个构建时间计算示例:https://stackoverflow.com/a/57762635/738287