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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 23.02.2011, 13:44   #1
Dimarik
Форумчанин
 
Аватар для Dimarik
 
Регистрация: 18.04.2009
Сообщений: 688
По умолчанию резидентная программа (обработка функции 9h прерывания 21h)

Разбираю программу из калашникова. Должна менять выводимую строку и быть резиднетной. Некуоторое оказалось непонятным что автор написал. Кто может, прокомменте.
Код:
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h

Start:
	;переходим на метку инициализации. Нужно будет перехватить прерывание 21h,
	;а также оставить прогу резидентной в памяти
	
	;jz (jump if zero) и je (jump if equal) идентичны, выполняются если флаг нуля установлен на 1 
	;(если предыдущая команда сравнения была верной)
	Int_21h_proc proc
		cmp ah,9; проверяем, это функция 09h?
		je Ok_09
	
		jmp dword ptr cs:[Int_21h_vect];??????????????????????
		
		Ok_09:	
		;сохраним ренистры
		push ds
		push dx
		push cs; Адрес строки должен быть в ds:dx
		
		pop cs;;;;почему сразу же выталкиваем cs??? 
		
		;выводим нашу строку вместо той, которую должна была вывести программа, вызывающая 21-е прерывание
		mov dx, offset My_string
		pushf;????????????????????????????????
		call dword ptr cs:[Int_21h_vect];??????????????????????
		
		;восстанавливаем исспользуемые регистры
		pop dx
		pop ds
		iret; продолжим работу (выйдем из прерывания)
		;программа, выводязая строку считает, что на экран было выведено её сообщение, но на самом деле это не так
		
		;переменная для хранения оригинального адреса обработчика 21h
		Int_21h_vect dd ? ;??????????????????что значит знако вопроса
		My_string db 'моя строка$'
	Int_21h_proc endp
	
	; со следующей метки нашей прогаммы уже не будет в памяти.
	;она затрётся после вызоыва прерывания 27h
	Init:
	;установим наш обработчик (его адрес) на прерывание 21h. Это позволяет сделать функция
	;35h прерывания 21h
	mov ah, 35h
	;al указывает ветор прерывания, адрес которого нужно получить
	mov al,21h
	int 21h
	
	;??????????????????
	;теперь es:bx адрес (вектор) прерывания 21h (es - сегмент, bx - смещение)
	
	;??????форма записи?????????????????????????
	
	;почему не необорот?????????????????????????????????????????????????????????????
	mov word ptr Int_21h_vect, bx
	mov word ptr Int_21h_vect+2, bx
	;адрес сохранили, теперь вызываем прерывание:
	mov ax, 2521h
	;???????????????????????????????????????????????
	;;.что тут делаем? почему просто нельзя было написать call Int_21h_proc???
	mov dx, offset Int_21h_proc
	int 21h;???????????????????????зачем?
	
	;остаётся завершить программу, оставив её резидентной в памяти
	mov dx,offset Init;зачем? почему просто нельзя вызвать int 27h???
	
	int 27h
		
		
CSEG ends
end Start
1.
jmp dword ptr cs:[Int_21h_vect];??????????????????????
почему нельзя написать без cs?
2.

push ds
push dx
push cs; Адрес строки должен быть в dsx

pop cs;;;;почему сразу же выталкиваем cs???
вообще в книге было написано pop ds. Но это наверно опечатка, потому что из стека в обратном порядке должны извлекаться значения. Если же на самом деле cs, то какой имеет смысл загонять значение в стек и сразу же потом извлекать его?
3.
Зачем нужна pushf (втолкнуть флаги)??
4.
Код:
;??????????????????
	;теперь es:bx адрес (вектор) прерывания 21h (es - сегмент, bx - смещение)
Никак не могу понять со смещением. То пишет автор dsx, но это для строк.
А почему тут автор пишет про другие регистры? И где можно прочитать когда и где использовать какие регистры для сектора и смещения?
5.
Код:
;??????форма записи?????????????????????????
	
	;почему не необорот?????????????????????????????????????????????????????????????
	mov word ptr Int_21h_vect, bx
	mov word ptr Int_21h_vect+2, bx
Что тут вообще делается?

6.
Код:
;???????????????????????????????????????????????
	;;.что тут делаем? почему просто нельзя было написать call Int_21h_proc???
	mov dx, offset Int_21h_proc
	int 21h;???????????????????????зачем?
7.
Код:
;остаётся завершить программу, оставив её резидентной в памяти
	mov dx,offset Init;зачем? почему просто нельзя вызвать int 27h???
	
	int 27h
Dimarik вне форума Ответить с цитированием
Старый 24.02.2011, 15:18   #2
Dimarik
Форумчанин
 
Аватар для Dimarik
 
Регистрация: 18.04.2009
Сообщений: 688
По умолчанию

попробовал дабы лучше разобраться в этой теме написать программу, которая перехватывает 16е прерывание и изменяет код нажатой клавиши.
Вот только программа у меня скомпилироваться скомпилировалась, а во время работы вылазят разные ошибки:
this interput isnt't defined yet, its avaliable to custom functions. You can define this interput by modyfying interput vector table refer to the list of supported interputs and global memory table
это написал отладчик emu8086
16-битная MS-DOS пишет что CPU получил illegal instruction
CS:08da IP4e OP:8d d6 d7 00 4f
Код:
dima segment
assume cs:dima, ds:dima, es:dima, ss:dima
org 100;для *.com-файлов
Start:
        jmp Initialization;переходим на метку инициализации. Это будет надо, чтобы перехватить прерывание 16h
        int_16h_proc proc
                cmp ah,10h;проверяем, нажата ли клавиша
                je go_ok;если нажата - идём к метке
                ;если нет - перейдём на оригинальный обработчик прерывания 16h
                        jmp dword ptr cs:[Int_16h_vect]
                go_ok:
                ;клавиша нажата, в al помещён код клавиши
                mov al, 02Dh;помещяем в al код клавиши 45 dex
        iret;выход из обработчика прерывания
        
        Int_16h_vect dd ?;переменная для хранения адреса оригинального обработчика прерывания
        int_16h_proc endp
        
        Initialization:
        mov ax,3516h
        int 21h;функция 35h прерывания 21h определяет адрес прерывания 16h
        ;теперь es:bx - вектор нашего прерывания
        mov word ptr Int_16h_vect, bx
        mov word ptr Int_16h_vect+2, es
        ;итак, адрес сохранили. Теперь переходим на само прерывание
        mov ax, 2516h
        mov dx, offset int_16h_proc; ds:dx - адрес обработчика
        int 21h
        
        mov dx, offset Initialization
        int 27h;выходим из программы но оставляем её резидентной
dima ends
end Start
P.S. но эти строки так остались покрыты мраком:
mov word ptr Int_16h_vect, bx
mov word ptr Int_16h_vect+2, es
особенно вторая, где +2. Что это такое О_О вообще непонятно
Dimarik вне форума Ответить с цитированием
Старый 25.02.2011, 10:38   #3
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Что это такое О_О вообще непонятно
А что тут непонятного?. Вектор это указатель. А указатель в ДОС если мне память не изменяет состоит из двух частей - базы и смещения. Это в 32 битке уже можно указатель в один реестр впихнуть а в ДОСе 16-ти битном такого нельзя было.
Но указатель указателем. вот и получается что вектор прерывания весит 32 бита, и выбирать его нужно двумя операциями по словам каждая.
потому читай внимательно фразу:
Цитата:
теперь es:bx - вектор нашего прерывания
т.е. функа записывает DWORD указатель в два регистра, разбивая его на две половинки:
Цитата:
mov word ptr Int_16h_vect+2, es
Сегмент, где находится процедура-обработчик прерывания а
Цитата:
mov word ptr Int_16h_vect, bx
смещение.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Резидентная программа lilufonel Паскаль, Turbo Pascal, PascalABC.NET 0 25.05.2010 01:27
Резидентная программа. Работа с буфером клавиатуры Vohakisa Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 4 21.06.2009 00:16
Резидентная программа! Nemesisking Общие вопросы C/C++ 8 29.09.2007 08:46