2011-07-28 23 views
7

Tôi đã cố gắng viết các chương trình TSR (Chấm dứt ở lại) (nói chung) trong Assembly (16-bit) cho MS-DOS. Tôi đã đọc qua một trang Wikipedia trên TSR và cũng là một trang về cách sử dụng nó đặc biệt trong DOS (nhưng nó có vẻ là giảng dạy nó trong C và không hội trực tiếp). Tôi đã xem xét một trang web với nhiều tài liệu ngắt DOS và tìm this one, this one và một tài liệu khác có liên quan nhất đến các chương trình TSR. Tôi không thể đăng tất cả các liên kết bởi vì với tư cách là một người dùng mới, tôi có thể có tối đa 2 siêu liên kết trên một bài đăng.Trợ giúp Viết (các) Chương trình TSR trong Hội đồng NASM cho DOS

Vì vậy, tôi đã thử viết một chương trình TSR (dường như) rất đơn giản trong mô hình phẳng chế độ thực (định dạng tệp .COM) trong NASM. Dưới đây là các mã:

[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 

Khi tôi lắp ráp này và thực hiện nó trong DOS, thay vì trả lại cho hệ điều hành DOS nhắc nó bị treo hệ thống (không có hoạt động xảy ra ngoại trừ con trỏ phần cứng chỉ nhấp nháy dưới cửa sổ cuối cùng). Tôi đoán bộ nhớ rác có thể được thực hiện nhưng bạn nhận được điểm.

Ai đó có thể giúp bạn tìm ra vấn đề với mã này và/hoặc cung cấp lời khuyên chung về cách mã hóa TSR trong DOS? Cảm ơn trước, bất kỳ trợ giúp được đánh giá rất nhiều!

+1

Ý của tôi chỉ nhập một thời gian dọc và zip trở lại 20 năm? – Keith

+0

@Keith Yep. Đừng nghĩ rằng tôi đang viết mã này như một ngôn ngữ chính (tôi cũng mã Java), tôi chỉ cần biết làm thế nào để mã một TSR trong hội cho mục đích trình diễn. – Mindstormscreator

+1

Dude, bạn đang làm khảo cổ học lập trình .. 1 cho điều đó! –

Trả lời

3

Tôi đã tìm ra. Sau khi xem qua một vài nguồn tin hơn, tôi phát hiện ra rằng đoạn mã này:

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

cần phải được một cái gì đó như thế này:

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

vì những tài liệu tham khảo bộ nhớ đang tham chiếu từ các phân đoạn dữ liệu, mà không phải là thiết lập từ người gọi của TSR. Vì vậy, về cơ bản tôi đã tham khảo dữ liệu từ một cái gì đó khối dữ liệu của người khác ...

này cũng có thể được thực hiện bằng cách đặt CS trong DS (và sau đó đặt giá trị ban DS trở lại) như thế này:

push DS 
push CS 
pop DS 
; Memory references.... 
pop DS 
Các vấn đề liên quan