Учебник по ассемблеру (ASM)
 

Ассемблер в примерах - Перехват прерывания в резиденте

Вопрос:
Нужно сделать резидент который бы перехватывал бы ДОС прерывание «вывод строки на экран» и копировал эту строку в файл. Я тут начал это делать но столкнулся с проблемой я не могу использовать прерывания в резиденте так как сам их перехватываю. И не уверен что правильно определил по какому адресу находится строка.
.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

   Вперёд
   Содержание
Редукционный клапан смотри здесь.