帮助在DOS的NASM汇编中编写TSR程序 [英] Help Writing TSR Program(s) in NASM Assembly for DOS

查看:213
本文介绍了帮助在DOS的NASM汇编中编写TSR程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试在MS-DOS的汇编语言(16位)中编写TSR(终止驻留)程序(通常).我已经阅读了维基百科页面 在TSR上以及在DOS中专门使用它的页面(但它似乎是在用C而不是直接在Assembly中进行讲授).我查看了一个包含大量DOS中断文档的站点,并找到了这一个,以及与TSR计划最相关的另一个.我无法发布所有链接,因为作为新用户,我在帖子中最多可以有2个超链接.

I've been trying to write TSR (Terminate-Stay-Resident) programs (in general) in Assembly (16-bit) for MS-DOS. I've read through a Wikipedia page on TSR and also a page on using it specifically in DOS (but it seems to be teaching it in C and not Assembly directly). I've looked at a site with tons of DOS interrupt documentation and find this one, this one, and another most relevant to TSR programs. I can't post all of the links because as a new user I can have up to 2 hyperlinks on a post.

因此,我尝试在NASM中以实模式平面模型(.COM文件格式)编写一个(看似)非常简单的TSR程序.这是代码:

So, I've tried writing a (seemingly) very simple TSR program in real mode flat model (.COM file format) in NASM. Here's the code:

[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提示符,而是挂起系统(除了硬件光标在最后一个提示符下闪烁以外,没有其他活动发生).我猜可能正在执行内存垃圾,但是您明白了.

When I assemble this and execute it inside DOS, instead of returning back to the DOS prompt it hangs the system (no activity occurs except the hardware cursor just blinks below the last prompt). I guess memory garbage might be executing but you get the point.

任何人都可以帮助找出该代码的问题和/或提供在DOS中编码TSR的一般建议吗?预先感谢,非常感谢您的帮助!

Could anybody please help to either figure out what the problem with this code is and / or offer general advice for coding TSR's in DOS? Thanks in advance, any help is very much appreciated!

推荐答案

我知道了.在查看了更多其他资源之后,我发现了以下代码:

I figured it out. After looking through a couple more sources, I discovered that this code:

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的调用者设置的.所以基本上我是从其他数据块中引用数据...

because those memory references are referencing from the data segment, which isn't set up from the caller of the TSR. So basically I was referencing data from something else's data block...

这也可以通过将CS放入DS(然后再将DS的原始值放回去)来实现,如下所示:

This can also be accomplished by putting CS in DS (and then putting DS's original value back) like this:

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

这篇关于帮助在DOS的NASM汇编中编写TSR程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆