gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 19:33:14 26 4
gpt4 key购买 nike

距离我上次在汇编中做一些事情已经过去了 23 年,我现在正在编写一个 DOS TSR 程序,只是为了好玩。

我有一个相当大的源文件,我决定将其拆分为较小的 .asm 文件。问题是我在计算 TSR block 的大小时遇到​​问题。使用单个 .asm 文件,我只需执行以下操作:

mov ax, offset end_of_code_label - offset start_of_code_label

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

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

有没有一种优雅的方法来做到这一点,或者至少不会被视为丑陋的黑客?

最佳答案

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

事实上,您的 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的目的指令的作用是通知汇编器和链接器 RTEXT , REND ,和ITEXT都应该是一个实际的段。这很重要,因为他们需要知道使用的任何地址都应该与组 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,您可能需要明确告诉汇编器相对于 PSPSEG 进行偏移。每次您使用 OFFSET 。例如mov dx, OFFSET PSPSEG:interrupt_handler .

关于assembly - 如何从多个 .asm 文件计算 TSR block 的总大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48393610/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com