1

我正在编写我的第一个 TSR。我知道我必须使用 INT 21H 的功能 31H。当我查看它时,我发现DX中的值是“段落中的内存大小”。我不知道如何计算,谷歌也没有帮助。我想知道如何计算代码段落中的内存大小。

我刚发现这个

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就是这样吗?

4

2 回答 2

2

段落是 16 字节的内存增量。在程序运行时动态计算程序大小将部分取决于用于编程的语言、程序模型和使用的段结构。通常,您要做的是将链接映射安排在整个程序映像的末尾放置一个几乎空的(可能分配了 1 个字节)段。单个未使用但已分配的字节被赋予一个符号,您可以在运行时引用该符号。

因为,在 16 位环境中编程时,段地址在段边界上递增,计算程序运行时间大小的过程是从程序的“段”部分中减去我们程序加载时间 PSP(程序段前缀)的段。上面提到的未使用的字节变量的地址。不同之处在于当您进入 TSR 时要求 DOS 保持加载的段落数。

请注意,在构建程序时仔细研究链接器生成的映射文件非常有用。至少您需要检查您在图像末尾设置的标记段确实是图像中的最后一件事。

另请注意,某些编程环境可能已经在其编程模板中为此目的设置了标记段。

于 2014-03-14T16:03:53.247 回答
2

在您的示例中,标签Install是指您的 TSR 在您的流程中的驻留部分的结束。通过获取标签,向右移动 4 并增加结果,您实际上除以 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

于 2019-09-02T21:20:12.460 回答