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

Перехватить прерывание ah=09h int 21h - изменить регистр символов

11.12.2016, 16:59. Показов 7246. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задача: Перекрыть девятую функцию прерывания 21h таким образом, чтобы в выводимой строке маленькие буквы заменялись большими, а большие на маленькие. Не могу понять в чём у меня ошибка, да и толковой информации по обработке прерываний так и не нашёл. Пожалуйста, посмотрите следующий код, может хоть вы найдёте ошибку( Да и если не трудно, напишите где можно доходчиво почитать про обработку прерываний в ассемблере. Заранее спасибо за внимание!
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
.model small
.stack
.data
    a dw ?
    old_handler dd ?
    string db 255 dup(?), '$'
.code
    assume ds:@data, es:@data
int_handler proc
    cld
    lea di, string
    lea si, string
    mov cx, a
again:
    lods string
    cmp al, 'A'
    jbe big_to_small
    cmp al, 'Z'
    jae big_to_small
    cmp al, 'a'
    jbe small_to_big
    cmp al, 'z'
    jae small_to_big
    jmp just_label
big_to_small:
    add al, 32
    jmp just_label
small_to_big:
    sub al, 32
just_label:
    stos string
    loop again
    iret
int_handler endp
 
main:
    mov ax, @data
    mov ds, ax
 
    mov ax, 3509h
    int 21h
    mov word ptr old_handler, bx
    mov word ptr old_handler + 2, es
    
    mov ax, 2509h
    mov dx, seg int_handler
    mov ds, dx
    mov dx, offset int_handler
    int 21h
    
    cld
    lea di, string
    mov cx, 255
    mov a, 0
cycle:
    mov ah, 01h
    int 21h
    cmp al, 13
    je string_ok
    stos string
    inc a
    loop cycle
string_ok:
    mov ah, 09h
    int 21h
    
    lds dx, old_handler
    mov ax, 2509h
    int 21h  
    
    mov ax, 4c00h
    int 21h
end main
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
11.12.2016, 16:59
Ответы с готовыми решениями:

Вывод строки на экран. Прерывание 21H функция 09H
Нужно просто вывести строку на экран string1 db 'Введите последовательность символов','$' ...

Резидентный обработчик функции ah=09h int 21h - в выводимой строке изменять регистр символов
Перекрыть девятую функцию прерывания 21h таким образом, чтобы в выводимой строке маленькие буквы заменялись большими, а большие на...

Резидентная программа - перехват прерывания int 21h ah=09h
Задание: перекрыть 9 функцию 21 прерывания в assembler. Помогите, плиз, разобраться как правильно ставить перекрывание. Решил с самого...

30
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6211 / 2445 / 403
Регистрация: 29.07.2014
Сообщений: 3,175
Записей в блоге: 4
11.12.2016, 19:55
Lici,
1. Если перехватываешь INT-9h, то после обработки, нужно отдавать управление старому вектору. А в идеале, для перехвата клавы подменяют не INT-9h, а INT-15h/4F. Структура обработчика будет проще.

2. Нет такой инструкции lods/stos string.
Есть 'stosb' (/w/d), которая пишет AL по адресу DI.
Соответственно, 'lodsb' читает из SI. Замени строки 15 и 31..

3. Проверки после метки 'AGAIN' вообще туши-свет. И это - внутри обработчика..
Зачем 4 штуки 'cmp', когда можно обойтись одной?
Диапазон ASCII-кодов всей латиницы лежит в пределах: 41h..7Ah, т.е. всего 39h подряд идущих кодов. Достаточно отнять от AL 41h, и проверить результат на 'меньше 40h'. Если результат больше, значит в AL лежит всё-что-угодно, только не латиница.

Заглавная от прописной отличается только пятым битом, поэтому достаточно его инверсии, для чего можно применить 'xor al,20h' (20h=00100000b):
Assembler
1
2
3
4
5
6
7
8
9
; введённый символ лежит в AL
@compare:
       mov  ah,al
       sub  ah,41h 
       cmp  ah,39h 
       ja   @skip
       xor  al,20h
       stosb
@skip: loop @compare
Правда, в диапазон 41h..7Ah попадают и 6 знаков: [\]^_', но т.к. они встречаются редко - ими можно пренебречь. В крайнем случае, можно исключить и их, сделав не 1, а 2 проверки. Четыре проверки - это явный перебор!
2
 Аватар для Ethereal
6773 / 2741 / 385
Регистрация: 17.02.2013
Сообщений: 4,048
11.12.2016, 20:07
Цитата Сообщение от Lici Посмотреть сообщение
Задача: Перекрыть девятую функцию прерывания 21h
В своей программе ты перекрываешь 9-е прерывание.

Добавлено через 3 минуты
Цитата Сообщение от R71MT Посмотреть сообщение
2. Нет такой инструкции lods/stos string.
Есть. Ассемблеры MASM и TASM различают какая именно lods используется из типа указанного операнда. Поскольку в данном случае
string db 255 dup(?), '$'
метка string типа байт, то ассемблер сообразит, что речь идет о lodsb.
В некоторых учебниках используется именно такой стиль, так-что то, что написал ТС вполне допустимо.

Добавлено через 1 минуту
З.Ы. Ассемблеры различают retn и retf ведь тоже из контекста. Это ведь тебе привычно писать просто ret . С lods stos movs scas та же история.
2
 Аватар для Kukuxumushu
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
11.12.2016, 20:07
Эммм...а что, разве можно перекрыть отдельную функцию прерывания???
1
 Аватар для Ethereal
6773 / 2741 / 385
Регистрация: 17.02.2013
Сообщений: 4,048
11.12.2016, 20:10
Цитата Сообщение от Kukuxumushu Посмотреть сообщение
Эммм...а что, разве можно перекрыть отдельную функцию прерывания???
Можно. В обработчике прерывания проверяешь значение AH и если оно то, что собираешься перекрыть - обрабатываешь сам, а нет так передаешь управление дальше по цепочке обработчиков прерываний.

Добавлено через 38 секунд
Цитата Сообщение от R71MT Посмотреть сообщение
Если перехватываешь INT-9h
Он собирался перехватывать int 21h, а int 9 перехватил по ошибке.
2
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6211 / 2445 / 403
Регистрация: 29.07.2014
Сообщений: 3,175
Записей в блоге: 4
11.12.2016, 20:25
Цитата Сообщение от Ethereal Посмотреть сообщение
Это ведь тебе привычно писать просто ret
.ну про retf я в курсе и использую его только в комках, а вот про lods ???
1
 Аватар для Ethereal
6773 / 2741 / 385
Регистрация: 17.02.2013
Сообщений: 4,048
11.12.2016, 20:51
Да так никто не делает (обычно сразу пишут lodsb), но те кто учатся по книгам начинают делать потому-что в каком-то учебнике так увидели.

Добавлено через 2 минуты
Можно даже так писать :
Assembler
1
lods        byte ptr ds:[si]
MASM-у и TASM-у это нравится.

Добавлено через 8 минут
Можно даже так :
Assembler
1
movs         byte ptr [di], [si]
или так
Assembler
1
movs         byte ptr [di], byte ptr [si]
Добавлено через 5 минут
Но ассемблер вообще-то тупой, так-что можно и так :
Assembler
1
movs        byte ptr [bp], byte ptr [bx]
Он проверяет только ТИПЫ операндов и есть ли переназначение сегмента
у источника. Остальное ему фиолетово. [bx] [bp] [si] [di] ему без разницы.
1
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6211 / 2445 / 403
Регистрация: 29.07.2014
Сообщений: 3,175
Записей в блоге: 4
11.12.2016, 20:55
Цитата Сообщение от Ethereal Посмотреть сообщение
Можно даже так
FASM не понимает таких извращений, и мой отладчик тоже..
Придётся придерживаться классики:
Миниатюры
Перехватить прерывание ah=09h int 21h - изменить регистр символов  
1
 Аватар для Ethereal
6773 / 2741 / 385
Регистрация: 17.02.2013
Сообщений: 4,048
11.12.2016, 21:01
Я говорил про синтаксис MASM и по наследству TASM. В MASM зачем-то была добавлена типизация. У операнда есть тип. Отсюда и все. По типу операнда определяем какой lods. А FASM - это бегство от синтаксиса MASM, ибо достал.
Зря и проверял. Я же дважды выше писал MASM и TASM. И TS на них писал.
1
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6211 / 2445 / 403
Регистрация: 29.07.2014
Сообщений: 3,175
Записей в блоге: 4
11.12.2016, 21:17
Допустим SI=200h, DI=300h.. Интересно в опкодах что сгенирит TASM? Может смогу фасму скормить?
Хотя и отладчик фыркает, а он то не фасмовский..
1
 Аватар для Ethereal
6773 / 2741 / 385
Регистрация: 17.02.2013
Сообщений: 4,048
11.12.2016, 21:21
Вот смотри, что я имею ввиду
BLABLA LABEL BYTE
тип у метки в MASM. Мне лень смотреть сохранилось ли такое дело в FASM, но в ассемблерах других архитектур метка - это всегда только адрес и ничего кроме адреса. Вот это и была исключительно дурная идея принести абстрактные типы туда, где они никому даром не нужны. Отсюда все эти lods операнд_некоторого_типа

Добавлено через 1 минуту
Цитата Сообщение от R71MT Посмотреть сообщение
Допустим SI=200h, DI=300h.. Интересно в опкодах что сгенирит TASM?
Вот это вот
Цитата Сообщение от Ethereal Посмотреть сообщение
movs byte ptr [bp], byte ptr [bx]
он генерит как байт A4 , т.е. movsb без примесей. В самом деле операнды типа байт, переназначения сегмента нет, что еще генерить ?
2
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6211 / 2445 / 403
Регистрация: 29.07.2014
Сообщений: 3,175
Записей в блоге: 4
11.12.2016, 21:32
Цитата Сообщение от Ethereal Посмотреть сообщение
что еще генерить
..а вот ты о чём!!! Теперь ясно..

Добавлено через 1 минуту
..можно даже и сегмент ставить другой, но только не у приёмника, который всегда должен быть ES
1
0 / 0 / 0
Регистрация: 23.06.2016
Сообщений: 29
11.12.2016, 22:25  [ТС]
Спасибо за ответ.
Цитата Сообщение от R71MT Посмотреть сообщение
Диапазон ASCII-кодов всей латиницы лежит в пределах: 41h..7Ah, т.е. всего 39h подряд идущих кодов. Достаточно отнять от AL 41h, и проверить результат на 'меньше 40h'. Если результат больше, значит в AL лежит всё-что-угодно, только не латиница.
А разве не лучше отнимать от 7A 39h и сравнивать потом с 41h (41h - 'a', первый символ латиницы в ASCII)
Цитата Сообщение от R71MT Посмотреть сообщение
1. Если перехватываешь INT-9h, то после обработки, нужно отдавать управление старому вектору. А в идеале, для перехвата клавы подменяют не INT-9h, а INT-15h/4F. Структура обработчика будет проще.
Разве? А можно ли это сделать через 25 и 35 функции 21 прерывания?
0
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6211 / 2445 / 403
Регистрация: 29.07.2014
Сообщений: 3,175
Записей в блоге: 4
11.12.2016, 22:33
Цитата Сообщение от Lici Посмотреть сообщение
А разве не лучше отнимать от 7A 39h и сравнивать потом с 41h
Нет не лучше, т.к. понадобятся 2 проверки на больше/меньше. Ты же не одну "а" будешь проверять..
Цитата Сообщение от Lici Посмотреть сообщение
через 25 и 35
..для этого они и существуют
1
0 / 0 / 0
Регистрация: 23.06.2016
Сообщений: 29
11.12.2016, 22:54  [ТС]
Цитата Сообщение от R71MT Посмотреть сообщение
Сообщение от Lici
через 25 и 35
..для этого они и существуют
А как мне тогда показать что мне нужна 9-ая функция 21 прерывания, если там указывается номер самого прерывания?
0
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6211 / 2445 / 403
Регистрация: 29.07.2014
Сообщений: 3,175
Записей в блоге: 4
11.12.2016, 23:12
Лучший ответ Сообщение было отмечено Lici как решение

Решение

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
old21  dw  0,0
 
;[...]
mov   ax,3521h             ; перехват вектора(21)
int   21h
mov   word[old21],bx
mov   word[old21+2],es
 
mov   ax,2521h             ; установка нового
mov   dx,new21
int   21h
 
;[...]
new21:                     ; обработчик(21)
        pusha 
        cmp    ah,09h      ; AH=9 ?
        jne    @Boom       ; нет.
        xor    al,20h      ; наш клиент!
@Boom:  popa   
        jmp    far dword [old21]     ; на оригинальный вектор..
;[...]
2
0 / 0 / 0
Регистрация: 23.06.2016
Сообщений: 29
11.12.2016, 23:12  [ТС]
Цитата Сообщение от Ethereal Посмотреть сообщение
Он собирался перехватывать int 21h, а int 9 перехватил по ошибке.
И как же мне исправить ошибку?)
0
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6211 / 2445 / 403
Регистрация: 29.07.2014
Сообщений: 3,175
Записей в блоге: 4
11.12.2016, 23:32
..по-второму кругу начинать объяснять что-ли? Вроде уже всё разжевали..
Попробуй собрать сам, что не получится - спросишь..

Добавлено через 3 минуты
pusha / popa можешь выкинуть из моего кода. Они там не нужны
1
0 / 0 / 0
Регистрация: 23.06.2016
Сообщений: 29
11.12.2016, 23:45  [ТС]
Цитата Сообщение от R71MT Посмотреть сообщение
..по-второму кругу начинать объяснять что-ли?
Нет), просто когда я отправлял то сообщение, я ещё не видел вашего ответа, и думал что вы сегодня уже не зайдёте, а хотелось именно сейчас разобраться, там всё понятно, спасибо большое. Ещё вопрос - у Вас в коде перед xor al, 20h нужно ещё вставить проверку на то, что введённый символ является латиницей? И ещё - куда прыгает jmp, когда возвращаем оригинальный вектор?
0
Эксперт Hardware
Эксперт Hardware
 Аватар для R71MT
6211 / 2445 / 403
Регистрация: 29.07.2014
Сообщений: 3,175
Записей в блоге: 4
11.12.2016, 23:56
Цитата Сообщение от Lici Посмотреть сообщение
что введённый символ является латиницей?
..да
Цитата Сообщение от Lici Посмотреть сообщение
куда прыгает jmp
..куда сохранял вектор функцией 3521h
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.12.2016, 23:56
Помогаю со студенческими работами здесь

Резидентный обработчик функции ah=09h int 21h - вывод строки "My String"
Помогите пожалуйста Надо написать резидентную программу, которая будет активироватьcя при попытки программ вывести строку на экран...

Будет ли прерывание int 21h работать в защищенном режиме
Будет ли прерывание int 21h функции ah=9 вывода строки работать в защищенном режиме?

Не работает функция 09h прерывания 21h
Дело в том, что программа, которую я пишу должна выкладывать информацию о блоках оперативной памяти вывод строки информации блока - с...

Перехват прерывания клавиатуры (int 09h) для замены нескольких символов
Перекрываю прерывание клавиатуры. Необходимо заменить пару букв цифрами. Но как-то пока слабо получается.(проблема написать сам...

Обработка прерывания int 09h: инверсия атрибутов символов всего экрана
Всем привет, мне нужна помощь. Я на ассемблер написал программу обработки прерывания, заменяю прерывание на свое. У меня делает лишнее...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru