2011-07-28 3 views
7

MS-DOS 용 어셈블리 (16 비트)에 TSR (Terminate-Stay-Resident) 프로그램을 작성하려고했습니다. 나는 위키피디아 페이지 TSR과 또한 그것을 DOS에서 특별히 사용하는 페이지를 통해 읽었습니다. (하지만 C로 직접 가르치는 것 같고 어셈블리는 아닙니다.) 나는 수많은 도스 인터럽트 문서가있는 사이트를 살펴본 결과 this one, this one 그리고 TSR 프로그램과 가장 관련이있는 사이트를 찾았습니다. 새 사용자는 게시물에 최대 2 개의 하이퍼 링크를 가질 수 있기 때문에 모든 링크를 게시 할 수 없습니다.도움말 DOS 용 NASM 어셈블리에 TSR 프로그램 작성

그래서, (겉으로보기에) 매우 단순한 TSR 프로그램을 NASM의 리얼 모드 플랫 모델 (.COM 파일 형식)로 작성하려고했습니다. 나는이를 조립하고 DOS 내부를 실행하면 대신 시스템을 (활동이 하드웨어 커서를 제외하고는 발생하지 않는다 단지 마지막 프롬프트 아래 깜박임) 중단하라는 메시지가 다시 DOS로 반환하는

[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에서 TSR 코딩에 대한 일반적인 조언을 제공 할 수 있습니까? 사전에 감사드립니다, 어떤 도움을 많이 주시면 감사하겠습니다!

+1

것은 그냥 입력 했 : 그러니까 기본적으로 나는이 또한 같은 DS에서 CS 퍼팅 (다음 다시 DS의 원래 값을 넣어)하여 수행 할 수 있습니다

뭔가 다른 사람의 데이터 블록에서 데이터를 ... 참조했다 시간 왜곡과 20 년 전의 지퍼? – Keith

+0

@Keith Yep. 기본 언어 (이 코드는 Java 코드)로 코딩하고 있다고 생각하지 마십시오. 데모 목적으로 어셈블리에서 TSR을 코딩하는 방법을 알아야합니다. – Mindstormscreator

+1

야, 프로그래밍 고고학을하고있어. 그거 +1! –

답변

3

나는 그것을 알아 냈다. 그 메모리 참조가 아닌 데이터 세그먼트에서 참조하고 있기 때문에

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

:

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

요구는이 같은 될 : 몇 가지 더 많은 소스를 통해보고 후, 나는이 코드를 발견 TSR의 호출자로부터 설정합니다.

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