Assembly 汇编TSR-我的程序崩溃了,我没有';我不知道原因

Assembly 汇编TSR-我的程序崩溃了,我没有';我不知道原因,assembly,x86,dos,tsr,Assembly,X86,Dos,Tsr,我正在写一个简单的TSR程序,但我发现了一个错误 我试图通过int90h执行它,但由于某种原因它崩溃了 我是TSR的新手,所以问题可能很简单 TSR: 主程序: .model small .stack 64 .data string db "Hey There" .code start: lea bx, string mov cx, 09 int 90H ; end mov ah, 4ch int 21H end start 你知道为什么

我正在写一个简单的TSR程序,但我发现了一个错误

我试图通过
int90h
执行它,但由于某种原因它崩溃了

我是TSR的新手,所以问题可能很简单

TSR:

主程序:

.model small
.stack 64
.data
    string  db  "Hey There"
.code
start:
    lea bx, string
    mov cx, 09
    int 90H
;   end
    mov ah, 4ch
    int 21H
end start
你知道为什么我的程序会崩溃吗?

十多年前,我为DOS a编写了一个TSR调试器(类似于),所以我可能忘了什么

无论如何,您的中断处理程序您不能假设除了
cs
指向您的中断处理程序段和
ip
(显然)指向您的中断代码之外的任何其他内容,这就是您所拥有的,并且您不能修改中断处理程序中的任何其他内容(您特别想要修改的内容除外)。您必须存储您使用的所有寄存器,但不能将它们推送到堆栈中,因为您不能假定还有任何堆栈。因此,请确保保留足够的内存来存储您在中断处理程序中修改的所有寄存器,并且在保存寄存器时,请记住使用
cs
作为段寄存器,而不是默认的
ds
,也不是
es
fs
gs
ss
,因为它们都可能指向内存中的任何位置,当然,也不包括保留给TSR的任何内存块。存储旗帜也是一个好主意

int 21h
在中断处理程序中通常应避免调用。您可以使用BIOS调用(
int10h
)或直接写入视频内存(但如果在TSR中写入视频内存,请先检查视频模式)。无论如何,写入TSR中的视频内存可能会导致问题,因为您不知道当前正在运行的程序如何使用它


如果您想确保在自己的中断处理程序中没有执行其他中断,那么在中断处理程序的开头,可以阻止大多数中断,IMHO是一个好主意。记住在iret之前允许通过sti进行中断。在我们使用iret指令从中断服务程序(ISR)返回之前,我们必须向第一个可编程中断控制器(PIC 1;8259A)发送一个带有“mov al,020h”+“out 20h,al”的“中断结束”信号(EOI)

另一种方法是跳转到旧的ISR,而不是发送EOI并返回iret

)---------------

拉尔夫·布朗x86/MSDOS中断列表(RBIL)



RBIL->inter61d.zip->PORTS.A
----------P00200003F---------------------------
端口0020-003F-PIC 1-可编程中断控制器(8259A)
另请参见:端口00A0h-00AFh“PIC 2”、INT 08“IRQ0”、INT 0F“IRQ7”
..有关详细信息,请查看RBIL。

)------------

要成为TSR,我们必须使用INT 27h终止应用程序的ISR部分,并保持常驻状态。

RBIL->inter61c.zip->INTERRUP.K
--------D-27--------------------
INT 27-DOS 1+-终止并驻留
DX=保持驻留的字节数(最大FFF0h)
CS=PSP的分段
返回:从不
注意:这是一个过时的呼叫
INT 22、INT 23和INT 24从PSP恢复
不关闭任何打开的文件
对于
DOS 2.x和60h,适用于DOS 3.0+;DOS 1.x没有最小值,这
在COMMAND.COM而不是DOS内核中实现此服务
另请参见:INT 21/AH=31h

)----------

它认为在我们的ISR中使用软件中断调用不是一个好主意。 因此我更喜欢直接写入视频存储器,例如在屏幕右上角写入一些数字以显示当前时间。

)------

用于设置和获取中断向量:

RBIL->inter61b.zip->INTERRUP.F
--------D-2125--------------------
INT 21-DOS 1+-设置中断向量
AH=25小时
AL=中断数
DS:DX->新建中断处理程序
注:此功能优于直接修改中断
向量表
一些DOS扩展器在该函数上放置API,因为它不是
在保护模式下直接有意义
在DR DOS 5.0-6.0下,此功能不使用任何
DOS内部堆栈,因此可随时调用;然而,
在Novell DOS 7.0-DR-DOS 7.02下,此函数不可重入。
自1998年5月29日起,DR-DOS 7.03不再使用任何内部堆栈和
更早地测试此函数,以允许最小的堆栈使用
除了IRET框架外,只需要两个单词,允许它
从INT 21h函数调用,特别是设备驱动程序。这
修复MCS SMB客户端
Novell NetWare(新的DOS请求程序除外)监视的偏移量
任何INT 24设置,如果等于启动时的值,则替换
它自己的处理程序允许处理网络错误;这将引入
INT 24处理程序偏移量小于br> 恰好与COMMAND.COM相同,但不会有其INT 24
已安装处理程序
另请参见:AX=2501h,AH=35h

--------D-2135--------------------
INT 21-DOS 2+-获取中断向量
AH=35小时
AL=中断数
返回:ES:BX->当前中断处理程序
注意:在DR DOS 5.0+下,此函数不使用任何DOS内部命令
堆栈,因此可以随时调用
另见:AH=25h,AX=2503h

设置中断向量的另一种方法是写入向量本身的内存位置:
从标签“TIMER\u INT”开始,将Timerinterrupt(8)设置为新的ISR的示例:


德克

我下周有考试,我对TSR一无所知。。我感谢你的帮助!!等等,这是学校的?找一个更好的老师(或更好的学校)
.model small
.stack 64
.data
    string  db  "Hey There"
.code
start:
    lea bx, string
    mov cx, 09
    int 90H
;   end
    mov ah, 4ch
    int 21H
end start
mov ax,0
mov ds,ax
cli
mov WORD PTR ds:[8*4],OFFSET TIMER_INT
mov WORD PTR ds:[8*4+2],cs
sti