|
Ассемблер в примерах - Перехват прерывания в резиденте
- Вопрос:
- Нужно сделать резидент который бы перехватывал бы ДОС прерывание «вывод строки на экран» и копировал эту строку в файл. Я тут начал это делать но столкнулся с проблемой я не могу использовать прерывания в резиденте так как сам их перехватываю. И не уверен что
правильно определил по какому адресу находится строка.
.286
.model tiny
.code
My_string db 'c:\123.txt$' ; д ©« ¤«п § ЇЁбЁ
My_string1 dw 40 dup(?) ; ЃгдҐа ¤«п б®еа ҐЁп бва®ЄЁ
Handle dw 0 ; yandl д ©«
Adres dw 0 ; ¤аҐб бва®ЄЁ
ORG 100h
start:
jmp setup ; ЏҐаҐ©¤Ґ¬ Є Їа®Ја ¬¬Ґ Ёбв ««пжЁЁ
; ђҐ§Ё¤Ґвп з бвм Їа®Ја¬¬л зЁв Ґвбп §¤Ґбм-----------------------------------------------------------------------------
int9_handler PROC FAR
cmp ah,9 ;Џа®ўҐаЁ¬: нв® дгЄжЁп 09h?
je Ok_09 ;…б«Ё в Є, в® ¬ҐвЄг Ok_09
jmp qwe5 ;…б«Ё Ґв в® ЁбЇ®«м§гҐ¬ бв ал© ўҐЄв®а ЇаҐалў Ёп
Ok_09:
pushf ; ‘®еа Ё¬ ॣЁбва д« Ј®ў
pusha
; c®еа Ё¬ бва®Єг ў ЎгдҐаҐ My_string1
push ds
push cs ;Ђ¤аҐб бва®ЄЁ ¤®«¦Ґ Ўлвм ў DS:DX
pop ds
mov cx,40 ; гбв ®ўЁ¬ бзҐвзЁЄ
mov si,0 ; Ё¤ҐЄб ¤аҐб ®«м
lea BX, My_string1 ; ў Bx ¤аҐб ЎгдҐа
mov Adres, dx ; ¤аҐб бва®ЄЁ ў DX
poperlo: ; жЁЄ« Є®ЇЁа®ў Ёп ў ЎгдҐа
mov ax,[adres+si] ; ў е 2 бЁ¬ў®« Ё§ бва®ЄЁ
MOV WORD PTR [BX], ax ; ў ЎгдҐа 2 бЁ¬ў®«
inc bx ; Є б«Ґ¤гойЁ¬
inc bx ; 2 Ў ©в ¬
inc si
inc si
loop poperlo
pop ds ;ў®бв ®ўЁ¬ DS
;®вЄалў Ґ¬ д ©« ¤«п §aЇЁбЁ
mov ax,3d02h ;ЋвЄалў Ґ¬ д ©« ¤«п звҐЁп Ё § ЇЁбЁ
mov dx,offset My_string ;?¬п ®вЄалў Ґ¬®Ј® д ©« ў DX
int 21
mov HANDLE,AX ;б®еаЁ¬ ®¬Ґа д ©«
mov ax,4200h ;“бв ®®ўЁ¬ гЄ § вҐ«м Є®Ґж д ©«
mov al,02h ;
xor cx,cx ;ЋЎг«Ё¬ ॣЁбвал
xor dx,dx ;
MOV BX,HANDLE
int 21
; § ЇЁбм ў д ©«
mov ah,40h ;‡ ЇЁиҐ¬ ў д ©« Є®¤ ¤«Ё®©
mov cx,80 ; 80 бЁ¬ў®«®ў
lea dx, My_string1 ; ЎгдҐа ®вЄг¤ ў®§м¬Ґ¬ еў®бв
int 21
;§ Єа®Ґ¬ д ©« ¤«п з⥨п
mov ah,3Eh ;‡ § Єа뢥¬ дa©«
MOV BX,HANDLE ;Ќ®¬Ґа дa©«a
int 21
popa
popf
qwe5:
jmp cs:[old_interrupt9] ; ЏҐаҐ©¤Ґ¬ Є бвa஬㠮Ўа Ў®взЁЄг INT 09h
old_interrupt9 DWORD ?
int9_handler ENDP
end_ISR label BYTE
; ------------- (Љ®Ґж १Ё¤Ґв®© з бвЁ Їа®Ја ¬¬л) --------------------------------------------------
setup:
mov ax,3521h ; ЋЇаҐ¤Ґ«Ё¬ § 票Ґ бв а®Ј® ўҐЄв®а INT 09h
int 21h
mov word ptr old_interrupt9,bx ; ‘®еаЁ¬ ҐЈ® ў ЇҐаҐ¬Ґ®©
mov word ptr old_interrupt9+2,es
mov ax,2521h ; “бв ®ўЁ¬ ®ўл© ўҐЄв®а ЇаҐалў Ёп INT 09h
mov dx,offset int9_handler
int 21h
mov ax,3100h ; ‡ ўҐаиЁ¬ Їа®Ја ¬¬г Ё ®бв ўЁ¬ ҐҐ з бвм १Ё¤Ґв® ў Ї ¬пвЁ
mov dx,OFFSET end_ISR ; ‘¬ҐйҐЁҐ Є®ж १Ё¤Ґв®© з бвЁ
mov cl,4
shr dx,cl ; Џ®¤Ґ«Ё¬ ҐЈ® 16, зв®Ўл г§ вм ¤«Ёг ў ЇaаaЈаaдaе
inc dx ; ЋЄагЈ«Ё¬ зЁб«® Ї а Ја д®ў ў Ў®«миго бв®а®г
int 21h
END start
- Ответ:
- Программа в приложении.
Адрес строки у Вас уже есть в паре регистров DS:DX.
Неизвестно только длина строки, которая ограничена символом '$'.
Именно поэтому копирование в строки в буфер лишнее, т.к. она может быть очень большой, а это может привести к сбою в работе Вашего резидента.
.286
.model tiny
.code
ORG 100h
start:
jmp setup; Перейдем к программе исталляции
; Резидетя часть прогрммы начитается здесь
My_string db 'c:\123.txt',0; файл для записии
Handle dw ?;handl файла
new21 PROC FAR
cmp ah,9;Проверим: это фукция 09h?
je Ok_09;Если т к, то метку Ok_09
db 0eah
old21h_o dw ?
old21h_s dw ?
;обработчик
Ok_09:
pushf;Сохраним регистр флагов
pusha
;запоминаем адрес строки
push ds
push dx
;определяем длину строки
mov si,dx
xor cx,cx
cld
;поиск символа "$"
CheckString: lodsb
inc cx
cmp al,'$'
jnz CheckString
;заопминаем длину строки
push cx;save string length
переходим в свой сегмент данных
push cs
pop ds
;открываем файл для зaписи
mov ax,3d02h;Открыв ем ф йл для чтеия и з писи
mov dx,offset My_string;Имя открыв емого ф йл в DX
;аналог INT 21h
pushf
call dword ptr cs:[old21h_o]
;устанавливаем указатель в конец файла
mov HANDLE,AX;сохрним номер файла
mov bx,ax
mov ax,4202h;Устаноовим указатель на коец файла
xor cx,cx;Оиулим регистры
xor dx,dx
;аналог INT 21h
pushf
call dword ptr cs:[old21h_o]
;запись в файл
mov ah,40h;Запишем в файл код длиой
mov bx,HANDLE
;востановим длину строки и её адрес
pop cx
pop dx
pop ds
;аналог INT 21h
pushf
call dword ptr cs:[old21h_o]
;переходим на свой сегмент
push ds
push cs
pop ds
mov ah,3Eh; закрывем фaйл
MOV BX,HANDLE;Номер фaйлa
;аналог INT 21h
pushf
call dword ptr cs:[old21h_o]
;востанавливаем регистры и возвращаемся в старый обработчик
pop ds
popa
popf
jmp dword ptr cs:[old21h_o]
new21 ENDP
;------------- (Коец резидетой части программы)
setup:
mov ax,3521h; Определим значеие старого вектор INT 21h
int 21h
mov old21h_o,bx;Сохрним его в перемеой
mov old21h_s,es
mov ax,2521h;Установим новый вектор прерывания INT 21h
mov dx,offset new21
int 21h
;оставить резидентной
mov dx,offset setup
int 27h
END start
| |