2011-07-28 14 views
7

He intentado escribir programas TSR (Terminate-Stay-Resident) (en general) en ensamblador (16 bits) para MS-DOS. He leído una página de Wikipedia en TSR y también una página sobre su uso específicamente en DOS (pero parece estar enseñándola en C y no directamente en Assembly). He visto un sitio con toneladas de documentación de interrupción de DOS y encuentro this one, this one, y otro más relevante para los programas de TSR. No puedo publicar todos los enlaces porque, como nuevo usuario, puedo tener hasta 2 hipervínculos en una publicación.Ayuda escribiendo programas TSR en NASM Assembly para DOS

Por lo tanto, he intentado escribir un programa TSR (aparentemente) muy simple en modo plano en modo real (formato de archivo .COM) en NASM. Aquí está el código:

[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 

Cuando armar esta y ejecutarlo en el interior de DOS, en vez de volver de nuevo al ambiente DOS se cuelga el sistema (no hay ninguna actividad, excepto el cursor de hardware simplemente parpadea por debajo de la última solicitud). Supongo que la basura de la memoria podría estar ejecutándose, pero entiendes el punto.

¿Alguien podría ayudarme a averiguar cuál es el problema con este código y/u ofrecer consejos generales para codificar los TSR en DOS? Gracias de antemano, cualquier ayuda es muy apreciada!

+1

Qué acabo de entrar un tiempo warp y zip atrás 20 años? – Keith

+0

@ Keith Yep. No creo que esté codificando en esto como un idioma principal (también código de Java), solo necesito saber cómo codificar un TSR en ensamblado con fines de demostración. – Mindstormscreator

+1

Amigo, estás haciendo arqueología de programación ... ¡+1 por eso! –

Respuesta

3

Me di cuenta. Después de mirar a través de un par de más fuentes, descubrí que este código:

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

tiene que ser algo como esto:

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

porque esas referencias de memoria hacen referencia a partir del segmento de datos, que no es configurado desde la persona que llama del TSR. Así que básicamente se refería a los datos de algo bloque de datos de otra persona ...

Esto también se puede lograr poniendo CS en DS (y luego poner el valor original de DS vuelta) así:

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