Я пытался написать программы TSR (Terminate-Stay-Resident) (в общем) на ассемблере (16-битный) для MS-DOS. Я прочитал страницу Википедии
на TSR, а также на странице, посвященной его использованию в DOS (но, похоже, он преподает это на C, а не на ассемблере напрямую). Я посмотрел сайт с тоннами документации по прерываниям DOS и обнаружил этот , этот , а также другой наиболее актуальный для программ TSR. Я не могу опубликовать все ссылки, потому что, будучи новым пользователем, я могу иметь до 2 гиперссылок на сообщение.
Итак, я попытался написать (казалось бы) очень простую программу TSR в плоской модели реального режима (формат файла .COM) в NASM. Вот код:
[BITS 16]
[ORG 0x0100]
[SECTION .text]
Start:
; Get current interrupt handler for INT 21h
mov AX,3521h ; DOS function 35h GET INTERRUPT VECTOR for interrupt 21h
int 21h ; Call DOS (Current interrupt handler returned in ES:BX)
mov WORD [v21HandlerSegment],ES ; Store the current INT 21h handler segment
mov WORD [v21HandlerOffset],BX ; Store the current INT 21h handler offset
; Write new interrupt handler for INT 21h
mov AX,2521h ; DOS function 25h SET INTERRUPT VECTOR for interrupt 21h
mov DX,TSRStart ; Load DX with the offset address of the start of this TSR program
; DS already contains the segment address, it is the same as CS in this .COM file
int 21h ; Override the INT 21h handler with this TSR program
; The TSR program will be called even when this portion uses INT 21h to terminate and stay resident
mov AX,3100h ; DOS function TSR, return code 00h
mov DX,00FFh ; I don't know how many paragraphs to keep resident, so keep a bunch
int 21h ; Call our own TSR program first, then call DOS
TSRStart:
push WORD [v21HandlerSegment] ; Push the far address of the original
push WORD [v21HandlerOffset] ; INT 21h handler onto the stack
retf ; Jump to it!
[SECTION .data]
v21HandlerSegment dw 0000h
v21HandlerOffset dw 0000h
Когда я собираю это и выполняю в DOS, вместо возврата к приглашению DOS система зависает (никаких действий не происходит, за исключением того, что аппаратный курсор просто мигает ниже последнего приглашения). Я предполагаю, что мусор памяти может выполняться, но вы понимаете, в чем дело.
Может ли кто-нибудь помочь разобраться, в чем проблема с этим кодом, и / или дать общий совет по кодированию TSR в DOS? Заранее спасибо, любая помощь очень ценится!