Исходник резидентной программы, которая через заданный промежуток времени выдает на экран заданное сообщение (asm)


Добавил:DMT
Дата создания:24 января 2008, 1:25
Дата обновления:24 января 2008, 1:25
Просмотров:8261 последний сегодня, 7:45
Комментариев: 0
Исходник резидентной программы, которая через заданный промежуток времени выдает на экран заданное сообщение.

Теория
Резидентная программа (terminate and stay resident, TSR) является специальным типом программы, которая остается в памяти после того, как вы ее запустили. Такое поведение находится в полной противоположности к поведению обычной прикладной программы, которая остается в памяти только в процессе выполнения. Эти программы называются резидентными еще и потому, что они требуют для себя блок памяти и обычно остаются в нем до тех пор, пока система не будет перезагружена. Фактически, они становятся почти постоянными жителями в памяти, подобно самой DOS.
Дня перехвата системного и установки своего прерывания обычно используются две функции DOS (функции 21h-го прерывания):
25h - установить вектор прерывания (Set Interrupt Vector);
35h - прочитать вектор прерывания (Get Interrupt Vector).
Все процедуры размещены в модуле установки программы в памяти, который будет делиться на две части: резидентная часть и установочная часть. Резидентная часть состоит из трех процедур:
1. Модуль предотвращения повторной установки программы в памяти и, одновременно, модуль выгрузки программы из памяти. Модуль будет устанавливаться вместо стандартного обработчика прерывания 2Fh. Сама программа будет закреплена за функцией 0FF00h, подфункция 0FFh. При наличии программы в памяти она будет отзываться на запрос прерывания 2Fh кодом 0FFh, возвращаемом в регистре AX.
2. Модуль контроля за истечением заданного времени будет устанавливаться на стандартное прерывание 1Ch (пользовательское прерывание таймера). Это прерывание в операционной системе вызывается 18,2 раза в секунду, следовательно, чтобы отсчитать промежуток времени в 10 заданных нам секунд надо пропустить 182 прерывания, после чего программа должна установить в некоторой ячейке, которую назовем "Флаг истечения времени", единицу, что будет являться сигналом для следующего блока, что заданное время ожидания истекло.
3. Модуль активизации и печати сообщения будет установлен взамен стандартного прерывания 28h. Это прерывание вызывается операционной системой в тот момент, когда она свободна и может выполнять запросы TSR программ. Модуль проверяет ячейку "Флаг истечения времени" и если там появляется единица, печатает заданное сообщение на экране, сбрасывает в ноль ячейку "Флаг истечения времени", сбрасывает счетчик модуля контроля за истечением заданного времени, устанавливая его в исходное состояние, и все начинается сначала

Текст программы

Код на ASM
  1. .286
  2. assume cs:code, ds:code, es:code
  3.  
  4. code segment
  5. org 2Ch
  6. EnvPtrlabel word ; сегмент окружения
  7.  
  8. org 100h
  9. start:jmp realstart
  10.  
  11.  
  12. Interval equ 36 ; 2 секунды
  13. TickCnt dw Interval
  14. TimeOut db 0
  15.  
  16. OldHandler2F dd ?
  17. OldHandler28 dd ?
  18. OldHandler1C dd ?
  19.  
  20. msgPastTimedb ' УРААААААААААААААААА! '
  21. msgPastTimeLen equ $-msgPastTime
  22.  
  23.  
  24. ; обработчик прерывания 2Fh
  25. Handler2F:
  26. cmp ah, 0FFh
  27. jne NotThisFunction
  28.  
  29. cmp al, 0
  30. jne Handler2FEnd
  31. mov al, 0FFh
  32.  
  33. Handler2FEnd:
  34. iret
  35.  
  36. NotThisFunction:
  37. jmp cs:OldHandler2F
  38.  
  39.  
  40. ; обработчик прерывания 28h
  41. Handler28:
  42. cmp cs:TimeOut, 1 ; надо печатать сообщение ?
  43. jne Handler28End
  44.  
  45. pusha
  46. push es
  47.  
  48. mov cs:TimeOut, 0
  49.  
  50. ; печать сообщения
  51. mov ah, 0Fh ; получение номера текущей
  52. int 10h ; страницы в bh
  53.  
  54. mov ax, cs ; настройка параметров и вывод
  55. mov es, ax ; строки сообщения
  56. mov bp, offset msgPastTime
  57.  
  58. mov cl, 25
  59. call random
  60. mov dh, al
  61.  
  62. mov cl, 80-msgPastTimeLen
  63. call random
  64. mov dl, al
  65.  
  66. mov bl, 2Eh
  67. mov cx, msgPastTimeLen
  68. mov ax, 1300h
  69. int 10h
  70.  
  71. pop es
  72. popa
  73.  
  74. Handler28End:
  75. jmp cs:OldHandler28
  76.  
  77. random:
  78. push es
  79. push bx
  80. push dx
  81. push cx
  82.  
  83. mov ah, 0
  84. int 1Ah ; cx:dx - время
  85.  
  86. mov cx, 0
  87. mov es, cx
  88. mov bx, dx
  89. mov al, es:bx
  90.  
  91. pop cx
  92. l1:
  93. cmp al, cl
  94. jb l2
  95. sub al, cl
  96. jmp l1
  97. l2:
  98. pop dx
  99. pop bx
  100. pop es
  101. ret
  102.  
  103.  
  104. ; обработчик расширенного прерывания таймера 1Ch
  105. Handler1C:
  106. dec cs:TickCnt
  107. jnz Handler1CEnd
  108.  
  109. mov cs:TickCnt, Interval
  110. mov cs:TimeOut, 1
  111.  
  112. Handler1CEnd:
  113. jmp cs:OldHandler1C
  114.  
  115. ; Конец резидентной части
  116. EndResidentlabel byte
  117.  
  118.  
  119. msgLoadTSR db ' Лабораторная работа 5 по ОС', 13, 10
  120. db ' TSR установлен'
  121. db '$'
  122. msgUnloadTSR db ' Программа выгружена из памяти'
  123. db '$'
  124.  
  125. realstart: ;Сразу запросим прерывание 2Fh-нет ли нашей ;программы в памяти
  126. mov ax, 0FF00h ;для этого занесем в ах запланированный нами;код функции
  127. int 2Fh ;обратимся к функции 2Fh
  128.  
  129. cmp al, 0FFh ;проверим поступивший из прерывания "отзыв"
  130. je Unload ;надо проверить ключ в строке параметров
  131. ;запуска программы
  132.  
  133. mov dx, offset msgLoadTSR
  134. mov ah, 9
  135. int 21h
  136.  
  137. ; сохраним адреса старых векторов прерываний(вектора прерывания 2F),
  138. mov ax, 352Fh ;которые мы планируем заместить своими процедурами
  139. int 21h ;используя станд. функцию 35h прерывания 21h
  140. mov word ptr OldHandler2F ,bx ;получим вектор es:bx
  141. mov word ptr OldHandler2F+2,es
  142.  
  143. mov ax, 252Fh ;с помощью стандартной функции 25h и прерывания 21h
  144. mov dx, offset Handler2F ;на место старого вектора установим адрес нашей процедуры
  145. int 21h
  146.  
  147. ;(проделаем то же самое) получение и сохранение вектора прерывания 1C
  148. mov ax, 351Ch
  149. int 21h
  150. mov word ptr OldHandler1C , bx
  151. mov word ptr OldHandler1C+2, es
  152.  
  153. mov ax, 251Ch
  154. mov dx, offset Handler1C
  155. int 21h
  156.  
  157. ; (проделаем то же самое) получение и сохранение вектора прерывания 28
  158. mov ax, 3528h
  159. int 21h
  160. mov word ptr OldHandler28 , bx
  161. mov word ptr OldHandler28+2, es
  162.  
  163. mov ax, 2528h
  164. mov dx, offset Handler28
  165. int 21h
  166.  
  167. ; освобождение блока окружения DOS
  168. mov ax, EnvPtr
  169. mov es, ax
  170. mov ah, 49h
  171. int 21h
  172.  
  173. ; резидентный выход
  174. mov dx, offset EndResident
  175. int 27h
  176.  
  177. Unload:
  178. ; получение и сохранение адреса старой программы
  179. mov ax,352Fh
  180. int 21h ; es - сегмент TSR части
  181.  
  182. ; восстановление старого вектора для 2Fh
  183. mov ax, 252Fh ;загрузим регистры ds:dx адресом старого вектора прерывания 2F,
  184. lds dx, es:OldHandler2F ;взятого из памяти нашей программы, кот. сейчас стоит резидентом
  185. int 21h
  186.  
  187. ; восстановление старого вектора для 1Ch
  188. mov ax, 251Ch
  189. lds dx, es:OldHandler1C
  190. int 21h
  191.  
  192. ; восстановление старого вектора для 28h
  193. mov ax,2528h
  194. lds dx, es:OldHandler28
  195. int 21h
  196.  
  197. ; удаление из памяти TSR (в ES - сегмент-адрес начала резид. прог.))
  198. mov ah, 49h
  199. int 21h
  200.  
  201. mov ax, cs
  202. mov ds, ax
  203. ;Выводим сообщение об освобождении
  204. mov dx, offset msgUnloadTSR
  205. mov ah, 9
  206. int 21h
  207. ;завершение программы, возврат а ОС
  208. mov ax, 4C00h
  209. int 21h
  210. code ends
  211.  
  212. end start
При использовании обязательна ссылка на http://DMTSoft.ru
После запуска программы на экране в произвольных местах с интервалом в 2 секунды начинают появлятся надписи "УРАААААААААААА! ". Повторный запуск программы удаляет резидентную часть из памяти.
up