• Предмет: Информатика
  • Автор: alenayakovleva404
  • Вопрос задан 3 месяца назад

Нужна помощь в исправлении кода tsr-программы на языке tasm. Задание: Составить программу замены на пробелы символов псевдографики на экране при нажатии горячей клавиши. Используйте прерывание 10H.
Код, который нужно исправить:
bogdan segment 'code'
assume cs:bogdan, ds:bogdan, ss:bogdan, es:bogdan
org 100h
begin: jmp main

; Функция для вывода элементов псевдографики
output_pseudographics proc
push ax bx cx dx
mov ah, 0ah
mov bh, 0
mov al, 176 ; код элемента псевдографики
mov cx, 5
int 10h
pop dx cx bx ax
ret
output_pseudographics endp

; Резидентная процедура (постоянно находится в памяти)
klaviatura proc far
push ds ax bx cx dx si di bp
in al,60h ; читаем скан-код(номер) клавиши из порта 60h
cmp al,16
je m1 ; нажата клавиша Q
; для остальных клавиш вызываем системную функцию
pop bp di si dx cx bx ax ds
int 60h ; просто совпали 60h
iret ; возврат из резидентной процедуры

; Добавляем обработку клавиши Q
m1:

; Чтение текущей позиции курсора
mov ah, 3 ; Функция 3 - получить позицию курсора
mov bh, 0 ; Номер страницы
int 10h ; Вызов BIOS прерывания 10H
mov cx, dx ; Сохраняем текущую позицию курсора

; Чтение текущего символа на экране
mov ah, 2 ; Функция 2 - чтение символа с атрибутом
mov bh, 0 ; Номер страницы
int 10h ; Вызов BIOS прерывания 10H
mov al, ah ; Сохраняем код символа в al

; Проверка, является ли символ элементом псевдографики (код 176)
cmp al, 176
jne not_pseudographics

; Если символ является элементом псевдографики, заменяем его на пробел
mov ah, 0ah ; Функция 0Ah - запись символа с атрибутом
mov al, 32 ; ASCII код пробела
int 10h ; Вызов BIOS прерывания 10H

not_pseudographics:
; Восстановление позиции курсора и возврат из обработчика
mov ah, 2 ; Функция 2 - установить позицию курсора
mov bh, 0 ; Номер страницы
mov dx, cx ; Восстанавливаем позицию курсора
int 10h ; Вызов BIOS прерывания 10H

pop bp di si dx cx bx ax ds
mov al, 20h ; Сигнал контроллеру прерываний
out 20h, al ; Об окончании аппаратного прерывания
iret ; Возврат из резидентной процедуры

finish EQU $ ; просто метка (пригодится дальше)
klaviatura endp

; конец резидентной процедуры
main proc near
call output_pseudographics ; Вывести псевдоэлемент при запуске

; 1- Получаем адрес программы обработки 9-го прерывания
mov ah,35h ; функция чтения вектора
mov al,9 ; номер вектора
int 21h ; адрес в ES:BX

; 2 - Записываем этот адрес в вектор 60h (он пока пустой)
cli ; запрет аппаратных прерываний
push ds
mov dx,bx ; bx-->dx
mov ax,es ; es-->ds
mov ds,ax
mov ah,25h ;писать вектор
mov al,60h
int 21h
pop ds
sti ; разрешение аппаратных прерываний
; 3 - адрес своей процедуры заносим в 9-тый вектор
mov ah,25h ; функция записи вектора
mov al,9h ; номер вектора
lea dx,klaviatura ; адрес нашей процедуры
int 21h
; 4 - оставляем свою процедуру резидентной в памяти
lea dx,finish ; адрес первого байта за резидентной частью
int 27h
ret
main endp
bogdan ends
end begin


Сорин: Тебе лучше с такими кодами на форумах писать

Ответы

Ответ дал: Сорин
1

Код в основном выглядит корректным, однако в твоем коде есть небольшая ошибка в строке, где хочешь установить позицию курсора.
bogdan segment 'code'

assume cs:bogdan, ds:bogdan, ss:bogdan, es:bogdan

org 100h

begin: jmp main

; Функция для вывода элементов псевдографики

output_pseudographics proc

   push ax bx cx dx

   mov ah, 0ah

   mov bh, 0

   mov al, 176 ; код элемента псевдографики

   mov cx, 5

   int 10h

   pop dx cx bx ax

   ret

output_pseudographics endp

; Резидентная процедура (постоянно находится в памяти)

klaviatura proc far

   push ds ax bx cx dx si di bp

   in al,60h ; читаем скан-код(номер) клавиши из порта 60h

   cmp al,16

   je m1 ; нажата клавиша Q

   ; для остальных клавиш вызываем системную функцию

   pop bp di si dx cx bx ax ds

   int 60h ; просто совпали 60h

   iret ; возврат из резидентной процедуры

   ; Добавляем обработку клавиши Q

m1:

   ; Чтение текущей позиции курсора

   mov ah, 3 ; Функция 3 - получить позицию курсора

   mov bh, 0 ; Номер страницы

   int 10h ; Вызов BIOS прерывания 10H

   mov cx, dx ; Сохраняем текущую позицию курсора

   ; Чтение текущего символа на экране

   mov ah, 2 ; Функция 2 - чтение символа с атрибутом

   mov bh, 0 ; Номер страницы

   int 10h ; Вызов BIOS прерывания 10H

   mov al, ah ; Сохраняем код символа в al

   ; Проверка, является ли символ элементом псевдографики (код 176)

   cmp al, 176

   jne not_pseudographics

   ; Если символ является элементом псевдографики, заменяем его на пробел

   mov ah, 0ah ; Функция 0Ah - запись символа с атрибутом

   mov al, 32 ; ASCII код пробела

   mov cx, 1 ; Количество повторений

   int 10h ; Вызов BIOS прерывания 10H

not_pseudographics:

   ; Восстановление позиции курсора и возврат из обработчика

   mov ah, 2 ; Функция 2 - установить позицию курсора

   mov bh, 0 ; Номер страницы

   mov dx, cx ; Восстанавливаем позицию курсора

   int 10h ; Вызов BIOS прерывания 10H

   pop bp di si dx cx bx ax ds

   mov al, 20h ; Сигнал контроллеру прерываний

   out 20h, al ; Об окончании аппаратного прерывания

   iret ; Возврат из резидентной процедуры

finish EQU $ ; просто метка (пригодится дальше)

klaviatura endp

; конец резидентной процедуры

main proc near

   call output_pseudographics ; Вывести псевдоэлемент при запуске

   ; 1- Получаем адрес программы обработки 9-го прерывания

   mov ah,35h ; функция чтения вектора

   mov al,9 ; номер вектора

   int 21h ; адрес в ES:BX

   ; 2 - Записываем этот адрес в вектор 60h (он пока пустой)

   cli ; запрет аппаратных прерываний

   push ds

   mov dx,bx ; bx-->dx

   mov ax,es ; es-->ds

   mov ds,ax

   mov ah,25h ;писать вектор

   mov al,60h

   int 21h

   pop ds

   sti ; разрешение аппаратных прерываний

   ; 3 - адрес своей процедуры заносим в 9-тый вектор

   mov ah,25h ; функция записи вектора

   mov al,9h ; номер вектора

   lea dx,klaviatura ; адрес нашей процедуры

   int 21h

   ; 4 - оставляем свою процедуру резидентной в памяти

   lea dx,finish ; адрес первого байта за резидентной частью

   int 27h

   ret

main endp

bogdan ends

end begin


alenayakovleva404: Спасибо большое что ответили. Но можете, пожалуйста, подсказать почему по нажатию на q псевдографика все равно не меняется на пробелы?
Вас заинтересует