2011-07-28 47 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