如何从多个.asm文件计算TSR块的总大小?

时间:2018-01-23 03:12:36

标签: assembly dos tasm

自上次我在汇编时做了23年后,我现在正在编写一个DOS TSR程序,只是为了它的乐趣。

我有一个相当大的源文件,我决定将其拆分为较小的.asm文件。问题是我在计算TSR块的大小时遇到​​问题。使用单个.asm文件,我只做了类似的事情:

mov ax, offset end_of_code_label - offset start_of_code_label

但是现在我将部分代码分散在几个源文件中,这种方法不起作用。

我发现通过手动指定链接顺序并确保最后一个.obj文件是带有“end_of_code_label”的文件,玩链接器会有所帮助。

有没有一种优雅的方式来做到这一点,或者至少是一些不被认为是丑陋黑客的东西?

1 个答案:

答案 0 :(得分:3)

控制事物顺序的最简单方法是根据需要在最终程序中将所有内容放入段中,然后使用首先链接的“模板”程序集文件来对段进行排序。默认情况下,链接器按照它们遇到的顺序对段进行排序,因此如果您在程序中使用的所有段都在它看到的第一个文件中,那么该文件将确定段的顺序。

您的TSR应该是单段COM文件这一事实使事情变得复杂,但仍然可以使用多个汇编程序段。汇编程序段不一定必须与程序使用的段一一对应。在这种情况下,您只需使用汇编程序段将事物分组在一起。

作为示例,您可以使用如下模板文件:

    EXTERN  init_start:NEAR
    PUBLIC  resident_end

PSPSEG  GROUP   RTEXT, REND, ITEXT

RTEXT   SEGMENT PUBLIC PARA 'RESIDENT'
    ORG 100h
start:
    jmp init_start
RTEXT   ENDS

REND    SEGMENT PUBLIC BYTE 'REND'
resident_end:
REND    ENDS

ITEXT   SEGMENT PUBLIC BYTE 'INIT'
ITEXT   ENDS

    END start

如果将所有驻留代码放在RTEXT部分和ITEXT部分中的初始化代码中,则前一代码将放在程序的开头,后面的代码放在最后。符号resident_end将位于中间,将程序退出代码后需要保留在内存中的代码分开。

GROUP指令的目的是通知汇编程序和链接器RTEXTRENDITEXT都应该是一个实际的段。这很重要,因为他们需要知道所使用的任何地址都应该相对于组PSPSEG,即程序正在使用的实际段。请注意,GROUP指令创建了一个别名,它实际上对链接程序中的事物顺序没有任何影响。

因为COM程序总是在程序开始时开始执行,所以我把代码放在这个跳转到初始化代码的模板中。如果您创建的是EXE,则不需要这样做,您可以将RTEXT留空,只使用END代替END start。具有入口点的文件将使用END代替入口点的标签。

这是一个旨在与上述模板链接的最小TSR:

    EXTERN  resident_end:NEAR
    PUBLIC  init_start

PSPSEG  GROUP   RTEXT, ITEXT

RTEXT   SEGMENT PUBLIC PARA 'RESIDENT'
    ASSUME  DS:NOTHING, SS:NOTHING, CS:PSPSEG
old_handler DD 0cccccccch
interrupt_handler:
    jmp [old_handler]
RTEXT   ENDS

ITEXT   SEGMENT PUBLIC BYTE 'INIT'
    ASSUME  DS:PSPSEG, SS:PSPSEG, CS:PSPSEG
init_start:
    mov ax, 3508h
    int 21h        ; get old timer interrupt handler
    mov WORD PTR [old_handler], bx
    mov WORD PTR [old_handler + 1], es
    mov dx, OFFSET interrupt_handler
    mov ax, 2508
    int 21h        ; set new timer interrupt handler

    mov ax, 3100h
    mov dx, OFFSET resident_end + 15
    shr dx, 4
    int 21h        ; terminate and stay resident
ITEXT   ENDS

    END

有必要在每个文件中重复GROUP指令,但您只需列出文件中使用的段。此代码是使用现代版本的MASM编写和测试的(仅链接),如果您使用TASM,则每次使用{{1}时,您可能需要明确告诉汇编程序相对于PSPSEG进行偏移。 }。例如OFFSET