2011-07-28 50 views
7

我一直试图在MS-DOS的Assembly(16位)中编写TSR(终止 - 驻留)程序(一般情况下)。我已经阅读了TSR上的维基百科页面 ,以及在DOS中专门使用它的页面(但它似乎是在C中而不是直接在Assembly中教它)。我查看了一个拥有大量DOS中断文档的网站,并找到了this one,this one,另一个与TSR程序最相关。我无法发布所有链接,因为作为新用户,我可以在帖子上最多包含2个超链接。因此,我尝试在NASM中以实模式平面模型(.COM文件格式)写一个(看似)非常简单的TSR程序。下面的代码:帮助在DOSM的NASM程序集中编写TSR程序

[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提示它挂起系统(没有发生活动,除了硬件光标只是闪烁下面的最后提示)。我猜内存垃圾可能正在执行,但你明白了。

任何人都可以请帮忙来弄清楚这个代码的问题是什么和/或提供在DOS下编码TSR的一般建议?在此先感谢,非常感谢任何帮助!

+1

难道我刚进入时间扭曲和缩减20年? – Keith

+0

@Keith Yep。 不要以为我是作为主要语言编写代码(我也是编写Java代码),我只需要知道如何在汇编中编写TSR以便进行演示。 – Mindstormscreator

+1

老兄,你正在做编程考古学.. +1为此! –

回答

3

我想通了。通过一对夫妇更期待的来源之后,我发现这个代码:

push WORD [v21HandlerSegment]  ; Push the far address of the original 
push WORD [v21HandlerOffset]  ; INT 21h handler onto the stack 

需求是这样的:

push WORD [CS:v21HandlerSegment]  ; Push the far address of the original 
push WORD [CS:v21HandlerOffset]  ; INT 21h handler onto the stack 

因为这些内存引用从数据段,这是不参考从TSR的主叫方设置。所以基本上我是引用自别的数据块中的数据...

这也可以通过把CS在DS(然后把DS的原始值回)这样来完成:

push DS 
push CS 
pop DS 
; Memory references.... 
pop DS