The easiest way to control the order of things is to put everything in segments, depending on where they should be in the final program, and then use the assembly template file, which you link first to arrange the segments. By default, the linker arranges the segments in the order in which they occur, so if you have all the segments used in your program in the first file, then it sees that this file determines the order of the segments.
, 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
.