Лидеры рейтинга

ID: 259041

Алексеев Владимир Николаевич

Мастер-Эксперт

1057

Россия, пос. Теплоозёрск, ЕАО


ID: 226425

Konstantin Shvetski

Модератор

314

Россия, Северодвинск


ID: 401284

Михаил Александров

Советник

277

Россия, Санкт-Петербург


ID: 137394

Megaloman

Мастер-Эксперт

177

Беларусь, Гомель


ID: 400669

epimkin

Профессионал

105


ID: 404002

sglisitsyn

6-й класс

42


ID: 242862

Hunter7007

Мастер-Эксперт

31

Россия, Омск


8.10.3

30.10.2021

JS: 2.10.3
CSS: 4.6.0
jQuery: 3.6.0
DataForLocalStorage: 2021-12-04 22:46:17-standard


Создание программ на языке Assembler.

Администратор раздела: Зенченко Константин Николаевич (Старший модератор)

Консультация онлайн # 201516

Раздел:  Assembler
Автор вопроса: kolyatimushev (Посетитель)
Дата: 15.10.2021, 22:37 Консультация закрыта
Поступило ответов: 1

Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:
Не могу разобраться как работает резидентная программа по книге Калашникова, помогите пожалуйста smile

Код
CSEG segment
assume cs:CSEG,es:CSEG,ds:CSEG,ss:CSEG
org 100h
Start:
	jmp Init
	Int_21h_proc proc
	cmp ah,9
	je Ok_09
	
	jmp dword ptr cs:[Int_21h_vect]

Ok_09:
	push ds
	push dx
	push cs
	pop ds
	mov dx,offset My_stirng
	pushf
	call dword ptr cs:[Int_21h_vect]
	
	pop dx
	pop ds
	iret
	Int_21h_vect dd ?
	
	My_stirng db 'Moya stroka!$'
	Int_21h_proc endp
	
Init:
	mov ah,35h
	mov al,21h
	int 21h
	
	mov word ptr Int_21h_vect,bx
	mov word ptr Int_21h_vect+2,es
	
	mov ax,2521h
	mov dx,offset Int_21h_proc
	int 21h
	
	mov dx,offset Init
	int 27h
CSEG ends
end Start

И так, как я понимаю:
1. Получаем адрес оригинального прерывания и сохраняем его сегмент и смещение в переменную Int_21h_vect
2. Загружаем адрес нашего обработчика, вместо оригинального. То есть мы не изменяем адрес как таковой оригинального обработчика, а изменяем адрес указывающий на него в таблице векторов. Таблица векторов это номера прерываний, указывающие где находиться это прерывание в памяти.
Далее мне не понятно следующее:
1.
Код
jmp dword ptr cs:[Int_21h_vect]

Я понимаю зачем в одном случае мы используем jmp, а в другом call. Так как в одном случае нам нужно просто отдать работу оригинального обработчика, а в другом вернуться, чтобы восстановить регистры.
Я не понимаю, что значит cs:[Int_21h_vect]. в Переменной и так храниться сегмент и смещение, зачем нам ещё раз указывать сегмент cs, который указывает на сегмент кода резидентной программы. Как вообще происходит прыжок если по сути указывается 2 сегмента и смещение.
2.
Код
push cs
pop ds
mov dx,offset My_stirng

Когда мы находимся в контрольной программе для проверки работы обработчика, при его вызове мы переходим на сегмент кода обработчика, остальные же сегментные регистры не изменяются и чтобы подменить исходную строку на нашу, мы подменяет сегмент данных контрольной программы, на сегмент кода резидентной для того чтобы подменить адрес исходной строки на нашу ( то что все сегменты находятся на одном адресе у com программ я помню). Мне не понятно зачем сохранять а затем восстанавливать после работа оригинального прерывания в стеке другие регистры, если они не изменяются.
Код
push ds
push dx
pop dx
pop ds

Остальное же мне вроде все понятно, Огромное спасибо вам smile

Доброе время суток!

Только я все равно не понимаю, что значит квадратные скобки и как их можно использовать.


Это косвенная адресация. А значит - будет прочитано значение по адресу cs:Int_21h_vect и оно попадет CS : IP, т.е. будет сделан переход.

Код [Assembler]
jmp dword ptr cs:Int_21h_vect

В синтаксисе MASM и TASM режиме совместимости с MASM(по умолчанию), это практически одно и тоже. Но если использовать другой компилятор FASM(к примеру) или TASM перевести в IDEAL, такой фокус уже не пройдет.

Код [Assembler]
jmp dword ptr cs:Int_21h_vect = адрес
jmp dword ptr cs:[Int_21h_vect] = значенние по этому адресу


Мне не понятно зачем сохранять а затем восстанавливать после работа оригинального прерывания в стеке другие регистры, если они не изменяются.


При срабатывании любого обработчика достоверно известны только CS : IP, остальное принадлежит прерваной программе. Поэтому, чтобы не нарушить ее работу, используемые регистры нужно сохранять и востановливать.
Этот код нужно расматривать вместе с контрольной программой.


Пример работы 211018t = контрольная программа
Код [Assembler]
CSEG segment
assume cs:CSEG,es:CSEG,ds:CSEG,ss:CSEG
org 100h
Start:
	mov	ah,9
	lea	dx,dbHello
	int	21h
ret
dbHello	db	10,13,' Hello kolyatimushev:$'
CSEG ends
end Start

211018 - Обработчик из Вашего вопроса.

Удачи!

Зенченко Константин Николаевич

Старший модератор
20.10.2021, 10:48
Мини-форум консультации # 201516

q_id

kolyatimushev

Посетитель

ID: 405378

1

= общий =    15.10.2021, 22:50
Экспертам раздела:

1.

Код
jmp dword ptr cs:[Int_21h_vect]


Я понимаю зачем в одном случае мы используем jmp, а в другом call. Так как в одном случае нам нужно просто отдать работу оригинального обработчика, а в другом вернуться, чтобы восстановить регистры.
Я не понимаю, что значит cs:[Int_21h_vect]. в Переменной и так храниться сегмент и смещение, зачем нам ещё раз указывать сегмент cs, который указывает на сегмент кода резидентной программы. Как вообще происходит прыжок если по сути указывается 2 сегмента и смещение.


Вы не поверите, когда отправил вопрос, мне тут же пришел ответ в голову.
Код
jmp dword ptr cs:[Int_21h_vect]

Означает считать адрес по адресу и перейти по нему. То есть означает прочитай два "слова" по это адресу сегмент(cs):смещение(Int_21h_vect).
smile Только я все равно не понимаю, что значит квадратные скобки и как их можно использовать. smile
Код
jmp dword ptr cs:[Int_21h_vect]

тоже самое как и
Код
jmp dword ptr cs:Int_21h_vect

q_id

Зенченко Константин Николаевич

Старший модератор

ID: 31795

2

= общий =    18.10.2021, 10:39
kolyatimushev:

Только я все равно не понимаю, что значит квадратные скобки и как их можно использовать.


Это косвенная адресация. А значит - будет прочитано значение по адресу cs:Int_21h_vect и оно попадет CS : IP, т.е. будет сделан переход.

Код [Assembler]
jmp dword ptr cs:Int_21h_vect

В синтаксисе MASM и TASM режиме совместимости с MASM(по умолчанию), это практически одно и тоже. Но если использовать другой компилятор FASM(к примеру) или TASM перевести в IDEAL, такой фокус уже не пройдет.

Код [Assembler]
jmp dword ptr cs:Int_21h_vect = адрес
jmp dword ptr cs:[Int_21h_vect] = значенние по этому адресу


Мне не понятно зачем сохранять а затем восстанавливать после работа оригинального прерывания в стеке другие регистры, если они не изменяются.


При срабатывании любого обработчика достоверно известны только CS : IP, остальное принадлежит прерваной программе. Поэтому, чтобы не нарушить ее работу, используемые регистры нужно сохранять и востановливать.
Этот код нужно расматривать вместе с программой следующей главы.

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

q_id

Зенченко Константин Николаевич

Старший модератор

ID: 31795

3

= общий =    18.10.2021, 10:57
kolyatimushev:


Пример работы 211018t = контрольная программа

Код [Assembler]
CSEG segment
assume cs:CSEG,es:CSEG,ds:CSEG,ss:CSEG
org 100h
Start:
	mov	ah,9
	lea	dx,dbHello
	int	21h
ret
dbHello	db	10,13,' Hello kolyatimushev:$'
CSEG ends
end Start

211018 - Обработчик из Вашего вопроса.

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

q_id

kolyatimushev

Посетитель

ID: 405378

4

= общий =    18.10.2021, 12:30
Зенченко Константин Николаевич:

Спасибо, Константин. Теперь стало понятнее smile

q_id

Зенченко Константин Николаевич

Старший модератор

ID: 31795

5

= общий =    18.10.2021, 16:06
kolyatimushev:

Для окончания понимания, пишем такой код:

Код [Assembler]
model	tiny
.code
org	100h
begin:	jmp	init
new21	proc
	jmp	dword ptr cs:[int21bx]
int21bx	dw	?
int21es	dw	?
new21	endp
init:	mov	ax,3521h
	int	21h
	mov	int21bx,bx
	mov	int21es,es
	push	bx
	push	es
	mov	ah,09
	lea	dx,dbOldInt
	int	21h
	pop	ax
	call	OutNum
	mov	al,':'
	int	29h
	pop	ax
	call	OutNum
	mov	ah,09
	lea	dx,dbNewInt
	int	21h
	push	cs
	pop	ax
	call	OutNum
	mov	al,':'
	int	29h
	lea	dx,new21
	mov	ax,dx
	call	OutNum
	mov	ax,2521h
	int	21h
	lea	dx,init
	int	27h
dbNewInt	db	10,13,'NewInt:=$'
dbOldInt	db	10,13,'OldInt:=$'
OutNum:	push	dx
	mov	bx,10h
	xor	cx,cx
@@01:	xor	dx,dx
	div	bx
	inc	cx
	push	dx
	or	ax,ax
	jnz	@@01
@@02:	pop	ax
	cmp	al,10
	jb	@@03
	add	al,7
@@03:	add	al,'0'
	int	29h
	loop	@@02
	pop	dx
	ret
	end	begin

Компилируем его и запускаем два раза smile

1)
F000:14A0 - оригинальный обработчик Dos
0192:0103 - наш новый первый обработчик
2)
0192:0103 - наш новый первый обработчик(для второго запуска - оригинальный обработчик Dos)
01AE:0103 - наш новый второй обработчик
О том, что это наш обработчик, говорит одинаковое смещение в сегменте = 0103
Как-то так.

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.

Лучшие эксперты раздела

Зенченко Константин Николаевич

Старший модератор

Рейтинг: 244

Коцюрбенко Алексей Владимирович

Старший модератор

Рейтинг: 197

Лысков Игорь Витальевич

Мастер-Эксперт

Рейтинг: 43

Nastya

1-й класс

Рейтинг: 3

Evgen aka Chuma

6-й класс

Рейтинг: 0

cain52

3-й класс

Рейтинг: 0