Assembly 中断21小时功能31小时DX值

Assembly 中断21小时功能31小时DX值,assembly,interrupt,x86-16,tsr,Assembly,Interrupt,X86 16,Tsr,我正在写我的第一份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 ;

我正在写我的第一份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,就是这样吗?

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

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

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


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

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

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

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


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

在您的示例中,标签
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编写的构建时计算示例:

在您的示例中,标签
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编写的构建时间计算为例:

一个段落是16字节。请检查我的编辑。好的,我明白了为什么我要使用偏移量*16?一段是16字节。请检查我的编辑。好吧,我明白了为什么我要用偏移量*16?