程序变量在内存地址自动变了,TSR

outsinre 2008-10-25 10:25:18
title TSR(COM)
.386
option casemap:none
codeseg segment use16
assume cs:codeseg,ds:codeseg,ss:codeseg,es:codeseg
org 100h
start: jmp init
Msg db 'System funtion invocation',0ah,0dh,'$'
TSR proc near
push ax
push dx
mov ah,09h
lea dx,Msg;在装入user.com 时 Msg下移了16个字节,结果输出字符串中有一部分乱码?????
int 21h
pop dx
pop ax
iret
TSR endp
init: cli
mov ax,25F2h
lea dx,TSR
int 21h
mov ax,3100h
lea dx,init+15
shr dx,4
sti
int 21h
codeseg ends
end start

这个部分是我写的驻留程序,用空闲号0F2H 新增一个中断,其实这个程序只是在屏幕上显示一个字符串,下面的程序调用这个驻留的中断:

title user TO call syscall(TSR)
option casemap:none
codeseg segment
assume cs:codeseg,ds:codeseg,ss:codeseg,es:codeseg
org 100h
start: mov ah,09h
lea dx,Msg
int 21h
mov ah,07h
int 21h
int 0F2h
mov ax,4c00h
int 21h
Msg db "To invoke the syscall.com",0dh,0ah,'$'
codeseg ends
end start

主要问题是:先运行syscall.COM 时没问题,但是运行user.com时原来的在SYSCALL.COM中的Msg变量在内存中地址下移了16个字节不知为何?这时调用驻留程序输出的字符串中有一部分是乱码,高手指点
...全文
128 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
cnzdgs 2008-10-27
  • 打赏
  • 举报
回复
系统自动保存的只有flag、cs、ip,以为是把这3个寄存器保存到栈中,sp会减6,所以说sp也会有变化。如果你的中断程序中需要的栈空间较大,应该先保存现有的ss、sp值,然后修改ss、sp,使其指向自己的堆栈,返回前再恢复原值。
sz_redtide 2008-10-27
  • 打赏
  • 举报
回复
笔误 retf--->iret
sz_redtide 2008-10-27
  • 打赏
  • 举报
回复
INT时FLAG,CS,IP入栈;
retf时FLAG,CS,IP出栈;

中断不会管其它寄存器的,使用要做现场保护把有影响的压栈保护。
outsinre 2008-10-27
  • 打赏
  • 举报
回复
问4楼:也就是说在调用INT中断时FLAG,CS,IP,以及其他寄存器(如sp)的值由系统自动保存到调用中断的程序的堆栈,执行完我写的TSR后系统自动恢复这些值?我在TSR中并没有保存falgs,cs,ip到堆栈;另外问一下如果要在TSR中用到SP,那么还得把sp切换到TSR程序的堆栈?
masterkill 2008-10-27
  • 打赏
  • 举报
回复
一旦检测到一个中断,就会发生如下事情:
1,标志被压入堆栈
2,IF和TF标志位均被清除
3,IP和CS寄存器均被压入堆栈
4,从中断向量表中去除中断向量并通过向量地址访问中断服务子程序。
正像8楼大叔说的那样,保存SS,SP的值,然后修改,再指向CS,IP
ex.
;获取中断向量
mov al,08h
mov ah,35h ;接收:AL=中断向量号,返回 es:bx=中断处理程序的段:偏移地址
int 21h
;设置中断向量
mov ax,seg my_program
mov ds,ax
mov dx,offset my_program
mov al,08h
mov ah,25h
int 21h
cnzdgs 2008-10-26
  • 打赏
  • 举报
回复
再补充一句,还有sp会变化,因为要把原flag、cs、ip入栈。
cnzdgs 2008-10-26
  • 打赏
  • 举报
回复
中断产生时,只有cs:ip是从中断向量表中取出,其它所有寄存器都保持发生中断前的值。
outsinre 2008-10-26
  • 打赏
  • 举报
回复
多谢指教,我后来也自己找出了问题,但就是不知为何非要初始化DS为cs的值,也即为何中断时ds的值没有转到中断程序中,而仍是调用程序的的ds?
cnzdgs 2008-10-25
  • 打赏
  • 举报
回复
不是Msg下移,是你没有初始化ds。这样改:
TSR proc near
push ds
push cs
pop ds
push ax
push dx
mov ah,09h
lea dx,Msg;在装入user.com 时 Msg下移了16个字节,结果输出字符串中有一部分乱码?????
int 21h
pop dx
pop ax
pop ds
iret
TSR endp

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧