Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.01.2022, 18:11   #1
Тимох
Пользователь
 
Регистрация: 13.04.2015
Сообщений: 32
По умолчанию Резидентная программа DOS

Привет! Рассматриваю пример резидентной программы для DOS из книги "Ассемблер на примерах. Базовый курс" Рудольф Марек.
Вот код программы:
Код:
.8086

code segment
	assume cs:code, ds:code, es:code, ss:code
	org 100h
	start:
		jmp Initialize
		
	; НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЯ 
	New_handler:
		push ax
		in al, 60h										; Читаем скан-код клавиши. 
		cmp al, 46h										; Сравниваем полученное значение с 46h(Scroll-Lock).
		jnz Pass_on
		call Color
	Pass_on:
		pop ax
		jmp dword ptr cs:[Old_vector]					; Передаём управление первоначальному обработчику.
		
	Old_vector	dd	0
	
	; ИЗМЕНЕНИЕ ЦВЕТА СИМВОЛОВ В КОНСОЛИ
	Color:
		push ax
		push cx
		push si
		push es
		mov ax, 3										; Перевод видеоконтроллера в 3-й текстовый видеорежим.
		int 10h
		xor si, si
		mov ax, 0B800h
		mov es, ax
		mov cx, 80*25
	RepeatC:
		inc si
		mov byte ptr es:[si], 4h
		inc si
		dec cx
		jnz RepeatC
		pop es
		pop si
		pop cx
		pop ax
		ret
		
	; ИНИЦИАЛИЗАЦИЯ РЕЗИДЕНТНОЙ ЧАСТИ ПРОГРАММЫ В ПАМЯТЬ
	Initialize:
		call Setup
		mov ax, 3100h
		mov dx, offset Initialize
		mov cl, 4
		shr dx, cl
		inc dx
		int 21h
		
	; ЗАМЕНА ВЕКТОРА ПРЕРЫВАНИЯ
	Setup:
		cli
		xor ax, ax
		mov es, ax
		mov ax, offset New_handler
		xchg ax, word ptr es:[9h*4]
		mov word ptr ds:[Old_vector], ax
		mov ax, cs
		xchg ax, word ptr es:[9h*4+2]
		mov word ptr ds:[Old_vector+2], ax
		sti
		ret
		
code ends
end start
Программу компилирую вот так:
C:\MASM\BIN>ML.EXE /c C:\Prog\Prog.asm
папки C:\MASM\BIN в папку C:\Prog
C:\MASM\BIN>link16 C:\Prog\Prog.obj, C:\Prog\Prog.exe, C:\Prog\Prog.map
C:\MASM\BIN>exe2bin C:\Prog\PROG.EXE C:\Prog\Prog.com

Затем запускаю командную строку. В ней запускаю получившуюся программу. При нажатии на клавишу Scroll Lock цвет символов в консоли не меняется, некоторые клавиши(например стрелки вверх и вниз) перестают работать в открытой командной строке.
Подскажите в чём может быть дело.
Тимох вне форума Ответить с цитированием
Старый 04.01.2022, 19:47   #2
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 472
По умолчанию

Скомпилировал и запустил в DOSBox, единственно, заменил код ScrollLock на CapsLock - на моей клавиатуре нет такой клавиши.

Заметил, что в подпрограмме Color сильно не по делу установка текстового видеорежима - я бы удалил эти две строки.

Запускайте в DOSBox - будет работать.
FPaul вне форума Ответить с цитированием
Старый 05.01.2022, 19:10   #3
Тимох
Пользователь
 
Регистрация: 13.04.2015
Сообщений: 32
По умолчанию

Спасибо за совет! Получается командная строка не поддерживает всего функционала DOS? В командной строке плохо работает резидентная часть программы?

Последний раз редактировалось Тимох; 05.01.2022 в 22:03.
Тимох вне форума Ответить с цитированием
Старый 05.01.2022, 23:18   #4
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 472
По умолчанию

Не буду врать - не знаю.
Резидент из книги Касаткина, запускаемый из командной строки WinXP, сильно затормаживал машину с i486, а на той же машине из под "чистого" DOS работал хорошо. Возможно, была не полная совместимость.

Вы - запустите в DOSBox и проверьте.
FPaul вне форума Ответить с цитированием
Старый 07.01.2022, 21:03   #5
spolyr
Пользователь
 
Регистрация: 30.03.2015
Сообщений: 17
По умолчанию

Попробовал, в досбокс, эффекта ноль, хоть не висит, уже хорошо )
spolyr вне форума Ответить с цитированием
Старый 08.01.2022, 20:04   #6
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 472
По умолчанию

Странно - тему начинал один пользователь, а продолжил другой...
Ну, да ладно - работа с клонами на усмотрение администрации.

Собственно, помимо запуска в DOSBox ещё советовал
Цитата:
Сообщение от FPaul Посмотреть сообщение
Заметил, что в подпрограмме Color сильно не по делу установка текстового видеорежима - я бы удалил эти две строки.
FPaul вне форума Ответить с цитированием
Старый 09.01.2022, 13:28   #7
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 472
По умолчанию

Нашёл книгу, набрал из неё программу - работает.
Её код частично отличается от вашего, в частности отсутствует установка текстового режима в теле резидента.

Для nasm
Код:
nasm 10_10.asm -fbin -l 10_10.lst -O9 -o 10_10.com
Код:
SECTION .text
        org     0x100
        jmp     initialize

new_handler:
        push    ax                      ;сохраняем значение АХ
        in      al,     0x60            ;читаем скан-код клавиши
        cmp     al,     0x46            ;сравниваем с 0x46 (Scroll-Lock)
        jnz     pass_on                 ;если нет,переходим к pass_on
        call    color                   ;вызываем подпрограмму
pass_on:
        pop     ax                      ;восстанавливаем значение АХ
        jmp     far     [cs:old_vector] ;передаем управление
                                        ;первоначальному обработчику
color:
        push    ax                      ;сохраняем в стеке значения
        push    cx                      ;регистров, которые
        push    si                      ;будем использовать
        push    es
        xor     si,     si              ;сбрасываем SI
        mov     ax,     0xB800          ;загружаем адрес сегмента в АХ
        mov     es,     ax              ;и в сегментный регистр
        mov     cx,     80*25           ;количество повторений
        .repeat:
                inc     si              ;-увеличиваем SI на 1
                mov     byte [es:si],   0x4     ;записываем цвет 0x04 - красный
                inc     si              ;увеличиваем на 1
                dec     cx              ;уменьшаем CX на 1
        jnz     .repeat                 ;переходим к .repeat, пока CX>0
        pop     es                      ;восстанавливаем все регистры
        pop     si
        pop     cx
        pop     ax
ret
old_vector      dd      0
initialize:
        call    setup                   ;вызываем регистрирацию своего
                                        ;обработчика
        mov     ax,     0x3100          ;функция DOS: делаем программу
                                        ;резидентной
        mov     dx,     initialize      ;вычисляем число параграфов:
                                        ;в памяти нужно разместить
                                        ;весь код вплоть до метки initialize
        shr     dx,     4               ;делим на 16
        inc     dx                      ;добавляем 1
        int     0x21                    ;завершаем программу и остаемся
                                        ;резидентом

setup:
        cli                             ;отключаем прерывания
        xor     ax,     ax              ;сбрасываем AX
        mov     es,     ax              ;таблица прерываний находится в
                                        ;сегменте 0
        mov     ax,     new_handler     ;с метки new_handler начинается
                                        ;новый обработчик прерывания
        xchg    ax,     [es:0x9*4]      ;вычисляем адрес старого вектора
                                        ;и меняем
                                        ;местами со значением AX.
                                        ;Теперь в таблице
                                        ;смещение нового обработчика,
                                        ;в AX - старого
        mov     [ds:old_vector],ax      ;сохраняем старый адрес
                                        ;в переменной old_vector
        mov     ax,     cs              ;адрес текущего сегмента - CS
                                        ;пишем в таблицу сегмент нового
                                        ;обработчика,
        xchg    ax,     [es:0x9*4+2]    ;в AX загружаем сегмент старого
        mov     [ds:old_vector+2],ax    ;сохраняем сегмент на 2 байта
                                        ;дальше old_vector
        sti                             ;включаем прерывания
ret                                     ;выходим из подпрограммы
dosbox_000.png

dosbox_001.png
FPaul вне форума Ответить с цитированием
Старый 19.01.2022, 18:44   #8
Тимох
Пользователь
 
Регистрация: 13.04.2015
Сообщений: 32
По умолчанию

FPaul С клонами Вы не общались, я временно отсутствовал на форуме.
Текстовый видеорежим в код добавил я. Встречал программу выводящую символ в видеобуфер, она
не работала пока не добавил текстовый режим отображения. Думал и в данной программе это поможет.

В этой программе удалил текстовый видеорежим и заменил скан код клавиши ScrollLock - 46h на
скан код клавиши F7 - 41h(можно было и другую клавишу). При запуске в командной строке
Windows зависания уже не было(вроде все клавиши работали), а изменения цвета не происходило
(хотя при повторном запуске компилятора или линковщика(не помню точно) в этой же консоли
некоторые их строки стали красными).
В DOSBox все работала правильно - цвет шрифта изменился. Совет использовать DOSBox помог. Я думал что командная строка Windows полностью эмулирует DOS, а про DOSBox был не в курсе.
Вероятно что командная строка Windows не очень корректно поддерживает DOS резиденты в памяти.

Вот получившийся код:
Код:
.8086

code segment
	assume cs:code, ds:code, es:code, ss:code
	org 100h
	start:
		jmp Initialize
		
	; НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЯ 
	New_handler:
		push ax
		in al, 60h										; Читаем скан-код клавиши. 
		cmp al, 41h										; Сравниваем полученное значение с 41h(F7).
		jnz Pass_on
		call Color
	Pass_on:
		pop ax
		jmp dword ptr cs:[Old_vector]					; Передаём управление первоначальному обработчику.
		
	Old_vector	dd	0
	
	; ИЗМЕНЕНИЕ ЦВЕТА СИМВОЛОВ В КОНСОЛИ
	Color:
		push ax
		push cx
		push si
		push es
		xor si, si
		mov ax, 0B800h
		mov es, ax
		mov cx, 80*25
	RepeatC:
		inc si
		mov byte ptr es:[si], 4h
		inc si
		dec cx
		jnz RepeatC
		pop es
		pop si
		pop cx
		pop ax
		ret
		
	; ИНИЦИАЛИЗАЦИЯ РЕЗИДЕНТНОЙ ЧАСТИ ПРОГРАММЫ В ПАМЯТЬ
	Initialize:
		call Setup
		mov ax, 3100h
		mov dx, offset Initialize
		mov cl, 4
		shr dx, cl
		inc dx
		int 21h
		
	; ЗАМЕНА ВЕКТОРА ПРЕРЫВАНИЯ
	Setup:
		cli
		xor ax, ax
		mov es, ax
		mov ax, offset New_handler
		xchg ax, word ptr es:[9h*4]
		mov word ptr ds:[Old_vector], ax
		mov ax, cs
		xchg ax, word ptr es:[9h*4+2]
		mov word ptr ds:[Old_vector+2], ax
		sti
		ret
		
code ends
end start

Последний раз редактировалось Тимох; 19.01.2022 в 19:12.
Тимох вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ассемблер. Резидентная программа StudArt Фриланс 2 01.06.2017 09:24
резидентная программа SchwarzeWolfin Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 23.05.2012 09:54
Резидентная программа Andr2011 Visual C++ 3 08.11.2011 16:49
Резидентная программа lilufonel Паскаль, Turbo Pascal, PascalABC.NET 0 25.05.2010 01:27
Резидентная программа! Nemesisking Общие вопросы C/C++ 8 29.09.2007 08:46