Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.59/32: Рейтинг темы: голосов - 32, средняя оценка - 4.59
0 / 0 / 0
Регистрация: 28.05.2008
Сообщений: 3

Резидентная программа: сообщение вывести 3 раза и перезагрузить компьютер

28.05.2008, 08:38. Показов 6575. Ответов 1
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Программа написана для MS-DOS. Резидентная. Каждые 10 сек выводит сообщение. Подскажите, что и как нужно исправить, чтобы сообщение вывелось 3 раза и после этого компьютер перезагрузился.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
code_seg segment
TSRprog proc far
    assume cs:code_seg
    org 100h
begin:
    jmp start
;----------------------------------------
New_2F  Proc                ;обработка мультиплексного прерывания
    cli                 ;на всякий случай запретим на время все прерывания в ОС
    cmp ax,08000h           ;проверим, а нашу ли программу вызывают?
    jne exit                ;если нет, то выйти из процедуры.
    mov ax, 0ABCDh          ;иначе – отправить пароль «я здесь» (см. выше   п1).
    sti                     ;разрешить опять все прерывания в ОС.
    iret                    ;выйти из прерывания
exit:
    sti                     ;разрешить опять все прерывания в ОС.
    jmp cs:[Old_2F]         ;и перейти по адресу старого обработчика прерывания 2F.
    Old_2F DD 0             ;это место под адрес старого обработчика прерывания 2F.
New_2F  endp
;----------------------------------------
New_1C Proc
    cmp cs:Cnt,182          ;проверяем прошло ли 10 сек.?
    jb  M2              ;если нет, то переход на увеличение счетчика (jb -переход при анализе беззнаковых величин)
    mov cs:flg_timer,1      ;сообщение можно выводить, поэтому установим в ячейке флага истечения контрольного времени 1
M2:
    inc byte ptr cs:Cnt     ;увеличить счетчик времени на 1
    jmp cs:[Old_1C]         ;и перейти по адресу старого обработчика прерывания 2F.
    Old_1C DD 0             ;это место под адрес старого обработчика прерывания 2F.
    Cnt DB 0                ;ячейка для счетчика тиков
    flg_timer DB 0          ;ячейка для флага истечения заданного времени
New_1C  endp
;----------------------------------------
New_28 proc
                        ;В первую очередь сохраним регистр флагов процессора, потому что сейчас
                        ;будем проводить проверку на истечение заданного времени, что изменит
                        ;регистр флагов
    pushf
                        ;теперь проверим – в ячейке флага контроля истечения заданного времени
                        ;установлена  единица?
    cmp cs:flg_timer,1
                        ;если нет, то время до вывода сообщения на экран еще не истекло и мы перехо-
                        ;дим на старый обработчик прерывания 28h
    jne M1
                        ;в противном случае активизируем модуль вывода сообщения на экран. Для чего
                        ;сначала сохраним в стеке регистры, которые сейчас начнем использовать. Иначе
                        ;мы испортим в них данные прерванной нами программы.
    push ax
    push bx
    push bp
    push es
    push cx
                        ;Запретим прерывания нашей программы другими программами
    cli
;========================================
    mov  ah, 0Fh            ;Читаем текущий видео режим
    int  10h                ;bh <- номер активной страницы дисплея
 
    mov  ax,cs              ;
    mov  es,ax              ;Выводимая строка
    mov  bp,offset curtime      ;
 
    mov  cl,25              ;Количество строк
    call random             ;Вызов random
    mov  dh,al              ;Строка начала вывода
 
    mov  cl,73              ;Количество колонок - количество символов (80-7)
    call random             ;Вызов random
    mov  dl,al              ;Колонка начала вывода
 
    mov  bl,2Eh             ;Атрибуты строки: желтые буквы на зеленом фоне
    mov  cx,7               ;Длина строки
    mov  ax,1300h           ;Вывод
    int  10h                ;
 
    jmp q1
 
random:
                        ;Сохраняем в стек регистры
    push es
    push bx
    push dx
    push cx
 
    mov  ah,0               ;Читаем часы
    int  1Ah                ;cx - старшая часть значения
                        ;dx - младшая часть значения
 
    mov  es,cx              ;
    mov  bx,dx              ;
    mov  al,byte ptr es:[bx]    ;Возвращаемое значение
 
    pop  cx             ;Восстанавливаем
l1:
    cmp  al,cl              ;Сравнение
    jb   l2             ;Если ниже
    sub  al,cl              ;Иначе CL - AL
    jmp  l1             ;Повторная проверка
l2:
                        ;Восстанавливаем сохраненные регистры
    pop  dx
    pop  bx
    pop  es
    ret
;========================================
;Внесем в регистр ES адрес начала видеопамяти ПЭВМ. Для тех, кто подзабыл
; – обратитесь к справочнику TECH HELP там указано, что видеопамять начинается
;с сегмента 0B800h. Поскольку сразу число в регистр ES занести нельзя, восполь-
;зуемся регистром BX как промежуточным буфером
;   mov bx,0B800h
;   mov es,bx
;Теперь загрузим смещение адреса выводимой текстовой строки в регистр BP
;(можно было – в любой другой, который может использоваться в качестве
;регистра смещения, например si или di, но нам понравился BP)
;   lea bp,curtime
;Регистр BX выберем в качестве регистра смещения индекса буквы на экране
;и занесем в него начальное значение 0
;   mov bx,0
;установим счетчик для цикла в 7 (по количеству букв в выводимой строке curtime)
;   mov cx,7
;Пометим начало цикла вывода строки текста на экран меткой vivod_on
;vivod_on:
;Возьмем из строки текста, подготовленного нами для вывода, первую букву
;   mov al,byte ptr cs:[bp]
;и поместим ее на экран в первую экранную текстовую ячейку
;   mov byte ptr es:[bx],al
;увеличим смещение BX на единицу, чтобы перейти к байту атрибутов текста на
;экране. Известно, что каждый символ текста на экране занимает в видеопамяти
;ПЭВМ два байта (слово). Младший байт хранит код самого символа, а старший –
;его цвет и цвет его фона (см. TECH HELP).
;   inc bx
;Занесем в байт атрибута символа его цвет: желтые буквы по зеленому фону
;(кодировка цвета символа и его фона тоже см. в TECH HELP).
;   mov al,2Eh
;   mov byte ptr es:[bx],al
;Увеличим счетчик букв на экране на 1
;   inc bx
;Увеличим счетчик букв в выводимой текстовой строке тоже на 1
;   inc bp
;Повторим цикл для вывода следующего символа
;   loop vivod_on
;После вывода всей строки, сбросим флаг готовности таймера и его счетчик,
;чтобы начался новый отсчет времени
 
 
q1:
    mov cs:flg_timer,0
    mov cs:cnt,0
                        ;разрешим внешние прерывания
    sti
                        ;и восстановим все сохраненные регистры ОБЯЗАТЕЛЬНО в обратной последова-
                        ;тельности их запоминания
    pop cx
    pop es
    pop bp
    pop bx
    pop ax
M1:
    popf
                        ;В заключение процедуры передадим управление старому обработчику
    jmp cs:[old_28]
                        ;А это область данных нашей процедуры New_28. Здесь хранится текстовая стро-
                        ;ка выводимая на экран ПЭВМ
    curtime db "Message"
    old_28 dd 0
New_28 endp
;----------------------------------------
start:
                        ;Во-первых, сразу запросим прерывание 2F – нет ли нашей программы в памяти?
                        ;Для этого занесем в AX запланированный нами код функции (см. выше процедуру
                        ;New_2F – мы там решили занять для своих нужд функцию 80 и подфункцию 00
    mov ax,08000h
                        ;Обратимся к функции 2F
    int 2Fh
                        ;Проверим поступивший из прерывания «отзыв». Наша программа должна ото-
                        ;зваться кодом 0ABCD (см.выше процедуру New_2F)
    cmp ax,0ABCDh
                        ;Если это так, то мы пытаемся второй раз установить программу – это не нужно,
                        ;а может быть мы хоти выгрузить ее из памяти? Надо проверить ключ в строке
                        ;параметров запуска программы, поэтому перейдем к метке ANALIZ
    je analiz
                        ;В противном случае начинаем установку программы резидентом в памяти
                        ;Для этого сначала сохраним адреса старых векторов прерываний, которые мы
                        ;планируем заместить своими процедурами. Начнем с вектора 28h. Используя
                        ;стандартную функцию 35h прерывания 21h получим этот вектор в  ES:BX
    mov ax,3528h
    int 21h
                        ;и сохраним его в специально подготовленной ячейке old_28 (см.выше)
    mov word ptr old_28,bx
    mov word ptr old_28+2,es
                        ;С помощью стандартной функции 25h прерывания 21h на место старого векто-
                        ;ра установим адрес нашей процедуры
    mov ax,2528h
    lea dx,new_28
    int 21h
                        ;Теперь то же самое проделаем с вектором 2Fh
    mov ax,352Fh
    int 21h
    mov word ptr old_2F,bx
    mov word ptr old_2F+2,es
    mov ax,252Fh
    lea dx,New_2F
    int 21h
                        ;и с вектором 1Сh
    mov ax,351Ch
    int 21h
    mov word ptr old_1C,bx
    mov word ptr old_1C+2,es
    mov ax,251Ch
    lea dx,New_1C
    int 21h
                        ;Разместим в регистре dx адрес начала НЕ РИЗЕДЕНТНОЙ части нашей программы
    lea dx,start
                        ;и, с помощью стандартного прерывания 27h завершим нашу программу, оставив
                        ;ее в памяти резидентной
    int 27h
                        ;Сюда мы попадаем, если наша программа обнаружена уже установленной в памяти
analiz:
                        ;Будем анализировать содержимое  строки параметров нашей программы.
                        ;Известно, что после запуска программы, содержимое командной строки операц-
                        ;онная система размещает по смещению 80h в PSP программы (см. TECH HELP,
                        ;PSP). Точнее по самому смещению 80h находится байт, в котором размещается
                        ;число, равное количеству символов в строке параметров. Получим его из PSP,
                        ;для чего смещение интересующего нас байта занесем в SI
    mov si,80h
                        ;потом загрузим этот байт в AL
    lodsb
                        ;и проверим, длина строки параметров не меньше трех символов? (Если Вы еще
                        ;не забыли, мы решили выгружать программу, если подадим в командной строке
                        ;параметр /u, а это, вместе с пробелом – как раз три символа)
    cmp al,3
                        ;если меньше, то выйти из программы, потому, что командная строка коротка
    jl bue
                        ;иначе перейдем на адрес следующего байта командной строки
    inc si
                        ;и возьмем из нее в AX два байта (слово)
    lodsw
                        ;проверим, это наш ключ /u ? (при этом помним, что в AX байты перевернуты –
                        ;сначала заносится старший, потом младший
    cmp ax,'u/'
                        ;если не равно, то это не наш ключ и программу завершаем
    jne bue
                        ;В противном случае начинаем модуль выгрузки программы из памяти
                        ;Для начала загрузим регистры ES:BX адресом нашей программы в памяти
                        ;для чего возьмем вектор любого из контролируемых ею прерываний например 28h
    mov ax,3528h
    int 21h
                        ;Теперь сохраним регистр ds, так как сейчас начнем его портить
    push ds
                        ; загрузим регистры DS:DX адресом старого вектора прерывания 1С взятого
                        ;из памяти нашей программы, которая сейчас стоит резидентом.
    lds dx,dword ptr es:old_1C
                        ;и возвратим его на «родное место» в таблицу векторов прерываний
    mov ax,251Ch
    int 21h
                        ;То же сделаем с прерыванием 28h
    lds dx,dword ptr es:old_28
    mov ax,2528h
    int 21h
                        ;И прерыванием 2F
    lds dx,dword ptr es:old_2F
    mov ax,252Fh
    int 21h
                        ;Восстановим регистр DS
    pop ds
                        ;Используя стандартную функцию 49h прерывания 21h, освободим память, зани-
                        ;маемую нашей резидентной программой. Функция освобождает память, сегмент
                        ;которой стоит в ES. А там как раз адрес начала нашей резидентной программы.
    mov ah,49h
    int 21h
                        ;Теперь надо освободить память, занятую блоком окружения программы. Надеюсь
                        ;Вы помните, что при запуске программы операционная система создает два бло-
                        ;ка управления памятью (MCB) – один для самой программы, а второй для тексто-
                        ;вых строк, взятых их файла autoexec.bat с ключем set. Этот блок называется
                        ;«блоком окружения» и его сегментный адрес операционная система заносит в
                        ;PSP программы в слово по смещению 02Ch от начала PSP. Возьмем оттуда этот
                        ;адрес и поместим его в ES
    mov es,word ptr es:[002ch]
                        ;После чего дадим команду освободить этот блок
    mov ah,49h
    int 21h
                        ;Теперь можно завершить программу и возвратиться в операционную систему
bue:
    mov ax,4c00h
    int  21h
TSRprog endp
code_seg ends
end begin
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.05.2008, 08:38
Ответы с готовыми решениями:

Резидентная программа, выводящая сообщение каждые 5 секунд
Нужно написать на ассемблере резидентную программу, выводящую на экран сообщение каждые пять секунд. Есть мысль такая: определить...

Перед загрузкой Windows просит как минимум 3 раза перезагрузить
Включая компьютер мне необходимо ждать пока он нагреется потом включается нормально все загружает но перед загрузкой Windows просит как...

вставить CD и перезагрузить компьютер
Всем привет. Подскажите пж в чем может быть проблема. при загрузке компа предлагает вставить CD и перезагрузить компьютер.

1
7 / 7 / 0
Регистрация: 20.08.2008
Сообщений: 44
20.08.2008, 15:39
перезагрузон - int 19h
вывести 3 раза - тот код котороый выводит сообщение обрамить следующим кодом:
Assembler
1
2
3
4
5
6
mov cx,3
l1:
push cx
; your code to print message
pop cx
loop l1
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.08.2008, 15:39
Помогаю со студенческими работами здесь

Не могу перезагрузить компьютер.
Приветствую вас всех. Заране прошу прошение если буду писать с ощибками. Я сам не русский петому такого происходит. Вот в моим компе...

Не удалось перезагрузить компьютер
Здравствуйте. Я хотел восстановить ось из бэкапа, но появилось окно: Восстановление Не удалось перезагрузить компьютер ОС...

Перезагрузить компьютер средствами С++
Скажите можно ли из своей программы перезагрузить, выключить, отправить в ждущий режим компьютер???

При нажатии клавиши Prt Sc программа должна записать содержимое экрана в файл (Резидентная программа)
Ребята, в универе задали написать код. Пользуюсь TASM, в ассмблере совсем не разбираюсь. Нужно &quot;написать программу вывода строк текста...

Не могу перезагрузить и выключить компьютер
Привет всем! Нужна помощь. Никак не могу перезагрузить и выключить компьютер. У меня стоит Chip Windows XP3. Возможно это произошло после...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
Установка Emscripten SDK (emsdk) и CMake на Windows для сборки C и C++ приложений в WebAssembly (Wasm)
8Observer8 30.01.2026
Чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. Система контроля версиями Git. . .
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru