这个SideKick是个好东东。 y@SI )&D
MDZPp;\)
下面的程序不是我写的。 b7y#uL1AE
i91k0q*di
用汇编编写DOS下的内存驻留程序(1) -p"}K~lt:
hW9U%-D
yg6o#;
kQp*+ras
xiV!\Z}
Nza@6nI"
2FY]o~@
绪言 caxO
xRo\
X|yVRQ?F`
{Iz"]Wh<f
0.1 内存驻留与中断 +6x}yc:yd
_S,UpR~2W
kt kS$
内存驻留程序英文叫Terminate and Stay Resident Program,缩写为TSR.这些程序加载进内存,执行完后,就驻留在内存里,当满足条件时,调到前台来执行。 _gEojuaN
k;K-6<^h
$Wjx$fD
内存驻留程序的常用形式有: Jpc% i8
C~WWuju'
?Yx2q_KZk
>诸如Borland 的SideKick弹出式实用程序 /Ny#+$cfk
=b8u8*ua
3a&HW
JBSx
>日历系统 bYmk5fpRG
T
oT('
FOteNQTj
>网络服务器 T7-yZSw-m
=sso )/3
/l+"aKW
2
>通讯程序 SW5n?Qj3-
`dWnu3r;
sm{/S*3
>本地的DOS扩展(如CCDOS,UCDOS等中文系统都属于这个范畴) p(cnSvg
P@Fx6
At'M? Q@v
>一些可恶的人利用TSR技术制作很多可恶的病毒程序,几乎所有的病毒程序都是TSR程序. S|T_<FCY
2.^CIJc
"<Yxt
"Z4
就象多任务系统调度一个进程有一个调度程序一样,在PC中从前台程序进入到一个TSR,也要有一个调度者,只是PC操作系统的调度不称为调度程序,而只称为触发机制.触发机制调度TSR执行在PC机上党称为激活一个TSR.触发机制主要有以下几种: x |gYxZ
>*uj
)u%
2PSkLS&IM
>硬件中断:党用的是键盘中断INT 9H,时钟中断INT 8H,通讯中断INT 14H,磁盘中断INT 13H等等. m.<or?l'y>
qDqy9u:g
f\r"7j
>软件中断:党用的是键盘中断INT 16H,时钟中断INT 1CH,DOS中断INT 21H,等等. %<r}V<OeR
"$P/ek
noLr185
>以上各种的结合. E@6gTx*
I
Bko"|e@
| )br-?2
从以上的触发机制可以看出,TSR和PC机的中断系统有着密切的关系.每种激活方式实际上都是与中断有关的.常用特殊的击键序列的识别码是通过截获INT 9H和INT 16H来实现.实际上不管TSR程序的哪一个环节,都与中断有着密切的关系.因此在具体进行TSR和程序设计之前,先介绍PC中断系统.在此只作简单说明. 3dJiu
M& )yr^
ArScJ\/Nwv
在PC机内存的最低端(0000H开始)的1K字节中,存放着256个指针即常说的中为向量或中断矢量(Interrupt vertor),每个中断向量都指向一个子程序,该程序称为中断处理程序(Interrup handler).一个中断向量由四个字节组成,有一个字是中断处理程序的偏移量值,后一个字是中断处理程序的段值.256中断向量一起称为中断向量表. 1]Cdfj6@
I2-ue 63 ?
D2J)qCK1)
手式计算中断向量的首址,可通过以下的公式来求得: T`,G57-5
7H|0.
RR|X4h0.
X号中断向量的首址=0000H:X*4 G`/4n@
`sA xk
6@"E*-z$
当产生一个中断时,处理器都按顺序执行以下步骤: ?a*w6,y.
0~P]Fw^w
{c~w
Ms#
>在堆栈上压入处理器的标志(相当于指令PUSHF). mwMu1#
FLZ9Rg
H?FiZy*[Y
>在堆栈上压入当前CS和IP值(相当于指令PUSH CS和PUSH IP). WJI}~/z;C
?2R!n"m-d
DMTc{
>关闭中断(CLI) t1~k+
zl|+YjR
v
V;]?
>从中断向量加载的CS和IP,执行中断处理程序. J@QOF+ &
$Ld-lQsL
-d thY(8
当执行完中断处理程序后,一般用IRET返回,它的作用是: k2fJ
hL&7D@
"a(e2H2&T4
>从堆栈上取出保存的IP和CS(相当于指令POP CS和PUSH CS). H/k]u)Gtv
}{kn/m/
!? H:?
>同时恢复中断前的处理器标志(相当于指令POPF). 0:-z+`RHE
R+!oPWfb
NJmx(!Xsh
中断有多种分类,由触发的原因和实现的性质来分,可分为硬件中断和软件中断,从操作系统分层实现来说,可以分成BIOS中断,BOS中断和用户中断. 5s;@ ;V
]
_W'-B
H= w6
一方面,BIOS和DOS通过中断系统向用户提供一个操作系统功能界面.也就是说用户(一般来说是前台程序)的功能主要是通过调用DOS和BIOS的中断服务来实现的,具体来说就是通过INT指令来实现的.另一方面,BIOS和DOS由中断系统所构成,BIOS对硬件成为高层的功能,并通过中断的形式向用户提供. w%::~]
CEBu[TT/9
L,!\PV|
如果在当前程序执行的同时,能将一块代码放在内存,把中断向量指向代码中的子程序,那么在当前程序执行中产生中断时,就有可能执行不属于当前程序和操作系统的代码,产生的中断可能是当前程序产生的软件中断,也可能是由硬件产生的硬件中断.这就是单任务的PC操作系统可能执行多于一个进程的简单说明. l8:!{I?s=
zo(
"v*d*q
_
nz
^+
在PC中断系统中有几个中断具有周期性,即INT 8H,INT 1CH和INT 28H.它们或者周期性被执行用于时间计时,或者周期性产生用于等待.它们是在实现TSR时进行轮询触发的基础.键盘中断(INT 9H和INT 16H)当用户击键时发生,利用它们是进行热键处理的基础.串行口通讯也是触发的一个重要机制.此外众多的软件中断也是触发的媒介. ,
%qP
F/,6Jh
X]n`YF7
$5\!ws<cZ
0.2 DOS的可重入性分析 wp'[AR}
KS1udH^Zc
!&cfX/y8
一个多任务操作系统之所以能使多个进行并存,是因为操作系统的大部分代码是可以了重的,对于临界资源有相应的PV操作,使得当调度一个新的进程时,能完整地保存前一个里程的现场,当再一次调度被挂起的进程时能象没有被中断一样继续执行. g-,lY| a
Y+kuj],h
yMzy!b Ky
对于PC机来说,代码的重入性比较弱,对临界资源没有PC操作.当我们用中断程序启动用户的TSR时,如果只保存标志和寄存器,以及当前进程一些信息,那么只保存了当前程序的一部分现场,DOS的临界资源不会自动保存.在进行TSR设计时,一定要了解PC操作系统的重入性和临界资源. f,|;eF-Z
;#+I"Ow
epG]$T![
重入性总是体现在代码上,所谓可重入代码的指这样的代码,即该代码被执行时还没有从中退出,由于某种原因又一次或者多次进入相同的代码,该代码每次的执行结果都是正确的,就说该代码是可重入的.相反,如果结果不正确,那么就就该代码是不可重入的.下面是一个可重入的子程序的例子: 2
E?]!9T~|
SL/'UoYm<
xFJT&=Af W
Add proc near 2Nx:Y+[
v;-0^s/P
-m[ tYp,q
cmp DS:word ptr [si],0 _zzT[}
kw} E0uY
I
Wm@pfC+g
je DonotAddTheValue G(wstHT;/
-ik=P]?
=[[I<[BZq
add ax,DS:word ptr [si] AZ4:3}
Zop/ MeI
.3jijc j
DonotAddTheValue: Z15=vsV
[z"oi'"fQ
&y7
=tEV
ret r\}?HS06
!I\eIV>0b
P)XR9&o':
Add endp Pa#Jw
o
K>5bb
:4x6dYNU
上面的例子不管在其中任何一处再一次执行该子程序,执行结果不变.为了说明,只举多种可能性中的一种. .gNziDO
F_i
"v5#
L@jpid95
mov ds,0100h ;ds=0100h G$)tp^%]
_|4QrZ$n(
ZoYllk
mov si,0010h ;si=0010h .:4*HB
1f1D^|
MmU`i ,z
mov ax,0001h ;ax,=0001h BHS@wh
j
|'u BkL0q
,Z
:2ba
call Add }}u`*&,g
Q[%G`;e #
mkPqxzxbrL
cmp 0100h:word ptr [0010h],0 ;Call Add subroutine S,udpQ7
>e(@!\ x
M= |is*t
push ds ;Interrupted GT80k]e.
B.smQt
;8f)p9vE
push si pAqPHD=
WvoIh4]
c6=XJvz
push ax H|,d`@U
2yD ?f8P4
dd;rnev+
mov ds,0200h ;ds=0200h Z-pZyDz
8|$g"?CU
1|s`z
mov si,0200h ;si=0020h )~S`[jV5
@HnahD
\zBZ$5 rE
mov ax,0003h ;ax=0003h ~p:hqi1+<+
'66nqJb*
Jt0/*^'
call Add t/%[U,m
Cs,Cb2[
U%Hcck'
cmp 0200h:word ptr [0020h],0 ;0200:0020h=0004h {5HQ=&
XbeT x
PMX'vA`
jne Fp"
c {
#c"05/=A
!,{N>{I
add ax,0200h:word ptr [0020h] ;ax=0007h :cIPX%S
ux*G*QZ
&~x |w6M]J
ret ;Return ;Xqi;EA
7/
fJQM
k_Sm ep
pop ax ;ax=0001h bD3 dT>(+
"vkM*HP
44w
"U%+
pop si ;si=0010h I2NMn5>
@3 +
Xr4k]'Mg
pop ds ;ds=0100h aqI m W
7l09
<lU(9)
L;&
iret ;Return to Add subroutine a;kiAJ'
d_f*'M2Gv
F9tWJJUsr
jne <Wj/A/
|Q@( <'8=
T-lP=KF=
add ax,0100h:word ptr [0100h] ;ax= 0001h n{qVF#N_
x_/l,4_
BZKg:;9
;0100h:0010h= 0002h qlg.\H:W~
Fi 7~JZZ
jeO`45O
;---------------------------------------- W>c*\)Xk !
O*N:.|dUw
u-bgk(u
;ax = 0003h EM1HwapD
:/Z1$xS
w@YPG{"j
ret k8SY=HP
foY]RkW9
/QCg E~
mov bx,ax YACx9K H
> PL}7f&:
FPZ@6
而下面的子程序是不可重入的: NXz/1ut%
V$iA3)7W%
7Up-a^k^`
Add proc near kp!(e0n
\f VX<L
\{Je!#
mov Temp,ax !Htl e %
/xr75|-8
9x(t"VPuS
mov ax,DS:word ptr [si] P1]F
0fR
KV'3\`v@LY
mq(K_
cmp ax,0 a3z_o)"
ZEpu5`
Sht3\cJ8
je DonotTheValue q1 BpE8
HCYy9
m(5LXHJnv
add ax,Temp /}%C'
Q&@<?K9
e5lJ)
_o
DonotTheValue: zWhzU|=8
o)CW7Y#?,
:xO43z
ret Uxe]T
hOs~/bM
VP ?Q$?a
Temp: C\;%IGn
{}gL*2:EW$
Nv=% R
dw 0 C.H(aX)7
Ei
Dpy#f}
}s#4m
Add endp W'E3_dj+