2011-07-28 11 views
7

Próbowałem napisać programy TSR (Terminate-Stay-Resident) (ogólnie) w Assembly (16-bit) dla MS-DOS. Przeczytałem stronę z Wikipedii na TSR, a także stronę dotyczącą jej używania w DOS (ale wydaje się, że uczę tego w C, a nie w Zgromadzeniu bezpośrednio). Przyjrzałem się stronie z mnóstwem dokumentacji przerwania DOS i znajdowałem this one, this one i inne najbardziej odpowiednie dla programów TSR. Nie mogę opublikować wszystkich linków, ponieważ jako nowy użytkownik mogę mieć do 2 hiperłączy w poście.Pomoc w pisaniu programów TSR w Zgromadzeniu NASM dla DOS

Tak, próbowałem napisać (na pozór) bardzo prosty program TSR w trybie rzeczywistym modelu płaskiego (format pliku. Com) w NASM. Oto kod:

[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 

Kiedy zmontować to i wykonać go wewnątrz DOS, zamiast wrócić z powrotem do DOS zawiesza system (brak aktywności występuje wyjątkiem kursora sprzętowego tylko miga poniżej ostatniego wiersza). Przypuszczam, że pamięć pamięci może być wykonywana, ale masz rację.

Czy ktokolwiek mógłby pomóc, aby dowiedzieć się, jaki jest problem z tym kodem i/lub zaoferować ogólne porady dotyczące kodowania TSR w DOS? Z góry dziękuję, każda pomoc jest bardzo cenna!

+1

Czy ja po prostu wpisać czas warp i zip z powrotem 20 lat? – Keith

+0

@ Kee Yep. Nie myśl, że koduję w tym jako główny język (ja również koduję Javę), po prostu muszę wiedzieć, jak zakodować TSR w Zgromadzeniu dla celów demonstracyjnych. – Mindstormscreator

+1

Dude, robisz programowanie archeologii .. +1 za to! –

Odpowiedz

3

Wymyśliłem to. Po patrząc przez jeszcze kilka źródeł, odkryłem, że ten kod:

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

musi być coś takiego:

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

ponieważ te referencje pamięci są przedstawieniu z segmentu danych, która nie jest skonfigurowany od dzwoniącego TSR. Więc w zasadzie byłem przedstawieniu danych z czegoś innego bloku danych ...

Można to również osiągnąć poprzez umieszczenie CS w DS (a następnie oddanie oryginalnej wartości DS powrotem) tak:

push DS 
push CS 
pop DS 
; Memory references.... 
pop DS 
Powiązane problemy