Некорректная работа процедуры, реализованной как часть обработчика int09 - Assembler

Узнай цену своей работы

Формулировка задачи:

Здравствуйте, хочу спросить. Написал TSR прогу в формате СОМ, которая должна выводить на экран скэн-коды нажатых клавиш. Формат вывода: 2-ух символьный код в 16-теричной системе плюс символ "h". При активации вместо кодов выводится только "h", а перед ним двойное пустое поле. Если, однако, запустить какую-либо программу после моей, то в поле для скэн-кодов отобразится мусор. Те же процедуры,
scan2hex
directout
не выполненные как часть резидентного обработчика, работают правильно, более того, при просмотре дампа памяти при активном TSR, 2-ух байтовое поле "string" содержит код нажатой клавиши. Запускаю под Вин-7 из DosBox. В чем проблема? Для краткости привожу только код обработчика, остальные процедуры нареканий не вызывают.
old_int9  dd ?
old_int2f dd ?  
string       db '??'
flag        db 0
khold   db ?
 
int9_handler proc
    pushf       
    push ax bx es di si
    in al,60h
    mov khold,al
    cmp al,0
    je outme
    mov bx,40h
    mov es,bx
    cmp byte ptr es:[17h],2 ;bit 1 set ? (LShift DOWN)  
    je nxt
    jmp same
nxt:
    cmp al,0fh                  ;TAB DOWN   
    je toggl    
    jmp same
toggl:
    mov bl,flag
    not bl
    mov flag,bl     
same:
        cmp flag,0
    je outme
    call scan2hex
    call directout
outme:      
    pop si di es bx ax
    popf
    jmp cs:[old_int9]   
        
;------------------subroutines for main handler----------------------   
 
_rout_intern:
    cmp al,0ah
    jae add_37
    add al,30h
    jmp nxt1
add_37:
    add al,37h
nxt1:  
    mov byte ptr cs:[si], al 
    inc si
retn  
scan2hex:
    mov si,offset string
    mov al,khold
    push ax
    shr al,4
    call _rout_intern
    pop ax
    and al,0fh
    call _rout_intern
retn        
directout:
    mov ax,0b800h           ;segment start
    mov es,ax
    mov di,072dh                    ;offset start+1
    mov byte ptr es:[di],0ch            ;pink color attribute for pos. +1
    add di,2                ;+3....
    mov byte ptr es:[di],0ch
    add di,2                        ;+5...
    mov byte ptr es:[di],0ch
    mov si,offset string                ;back to string offset+0
    mov di,072ch                    ;now symbol at pos. 0
    mov al, byte ptr [si]       ;the symbol at pos. 0
    mov byte ptr es:[di],al
    add di,2
    inc si
    mov al, byte ptr [si]       ;the symbol at pos. 2
    mov byte ptr es:[di],al
    add di,2
    mov byte ptr es:[di],'h'        ;the symbol at pos. 4, i.e., 'h'
retn 
int9_handler endp

Решение задачи: «Некорректная работа процедуры, реализованной как часть обработчика int09»

textual
Листинг программы
.286
text segment 'code'
assume cs:text, ds:text
org 100h
 
main proc
    jmp init
    
old_int9  dd ?
old_int2f dd ?  
string       db '??'
flag        db 0
khold   db ?
 
int9_handler proc
    pushf       
    push ax bx es di si
    in al,60h
    mov khold,al
    cmp al,0
    je outme
    mov bx,40h
    mov es,bx
    cmp byte ptr es:[17h],2 ;bit 1 set ? (LShift DOWN)  
    je nxt
    jmp same
nxt:
    cmp al,0fh          ;TAB DOWN   
    je toggl    
    jmp same
toggl:
    mov bl,flag
    not bl
    mov flag,bl     
same:
        cmp flag,0
    je outme
    call scan2hex
    call directout
outme:      
    pop si di es bx ax
    popf
    jmp cs:[old_int9]           
;------------------subroutines for main handler----------------------   
_rout_intern:
    cmp al,0ah
    jae add_37
    add al,30h
    jmp nxt1
add_37:
    add al,37h
nxt1:  
    mov byte ptr cs:[si], al 
    inc si
retn  
scan2hex:
    mov si,offset string
    mov al,khold
    push ax
    shr al,4
    call _rout_intern
    pop ax
    and al,0fh
    call _rout_intern
retn        
directout:
    mov ax,0b800h           ;segment start
    mov es,ax
    mov di,072dh            ;offset start+1
    mov byte ptr es:[di],0ch    ;pink color attribute for pos. +1
    add di,2                ;+3....
    mov byte ptr es:[di],0ch
    add di,2                ;+5...
    mov byte ptr es:[di],0ch
    mov si,offset string        ;back to string offset+0
    mov di,072ch            ;now symbol at pos. 0
    mov al, byte ptr [si]       ;the symbol at pos. 0
    mov byte ptr es:[di],al
    add di,2
    inc si
    mov al, byte ptr [si]       ;the symbol at pos. 2
    mov byte ptr es:[di],al
    add di,2
    mov byte ptr es:[di],'h'        ;the symbol at pos. 4, i.e., 'h'
retn 
int9_handler endp   ;-------------------------------------------------------------------------------------------------
int2f_handler proc 
    pushf
    cmp ax,0fafbh
    jne outhand
    mov ax,0fcfdh
    popf
    iret
outhand:
    popf                    ;DO NOT COMMENT OUT - any other executable will stall the system!
    jmp cs:[old_int2f]      
int2f_handler endp
end_ISR label byte
 
info   db 'TSR scan codes viewer - holding LShift, press & release Tab to toggle',10,13,'$' 
info1 db 'Occupying: $+ bytes after install$'
norun db 13,10,'!TSR is already installed!$'
 
wrd2char proc  
    mov cx, 0
    mov bx, 10
loop12:
    mov dx,0
    div bx
    push ax
    add dl,'0'
    pop ax
    push dx
    inc cx
    cmp ax, 0
jnz loop12
    mov ah, 2
loop13:
    pop dx
    int 21h
    loop loop13      
ret    
wrd2char endp
 
init:
    mov ah,9
    mov dx,offset info
    int 21h
    mov ax,0fafbh
    int 2fh
    cmp ax,0fcfdh
    jne canrun
    mov ah,9
    mov dx,offset norun
    int 21h
    mov ax,4c01h
    int 21h
canrun: 
    mov ax,3509h                
    int 21h
    mov word ptr [old_int9],bx      
    mov word ptr [old_int9+2],es
    mov ax,2509h                
    mov dx,offset int9_handler
    int 21h     
    mov ax,352fh
    int 21h
    mov word ptr [old_int2f],bx     
    mov word ptr [old_int2f+2],es   
    mov ax,252fh
    mov dx,offset int2f_handler
    int 21h
    mov ah,9
    mov dx,offset info1
    int 21h
    mov dx,offset end_ISR   
    add dx,16
    mov ax,dx
    call wrd2char   
    mov ah,9
    mov dx,offset info1+12
    int 21h
    mov dx,offset end_ISR
    mov ax,3100h    
    shr dx,4        
    inc dx      
    int 21h                     
main endp
text ends
end main

Объяснение кода листинга программы

  1. Процедура int9_handler обрабатывает прерывание от нажатия клавиш на клавиатуре.
  2. При поступлении прерывания сначала сохраняются регистры, затем из регистра AL считывается скан-код клавиши.
  3. Если бит 1 регистра AL (LShift) установлен, то выполняется подпрограмма toggl, которая меняет значение флага flag.
  4. В подпрограмме scan2hex сначала определяется начальный сегмент для вывода (0b800h), затем в регистре SI сохраняется смещение начала строки символов, а в регистре DI - смещение начала символа.
  5. Далее в цикле происходит вывод символов, при этом каждый символ выводится на экран в сегменте 0b800h.
  6. После обработки прерывания выполняется возврат в основную программу, при этом регистры SI и DI содержат смещения следующего символа.
  7. В подпрограмме directout сначала определяется начальный сегмент для вывода (0b800h), затем в регистре SI сохраняется смещение начала строки символов, а в регистре DI - смещение начала символа.
  8. Далее в цикле происходит вывод символов, при этом каждый символ выводится на экран в сегменте 0b800h.
  9. После обработки прерывания выполняется возврат в основную программу, при этом регистры SI и DI содержат смещения следующего символа.
  10. В подпрограмме wrd2char происходит преобразование числового значения в строку символов.
  11. В начале программы выполняется инициализация: в регистре AX устанавливается значение 0fafbh, которое затем передается в обработчик прерывания int2f_handler.
  12. Если в обработчике прерывания int2f_handler значение регистра AX не равно 0fcfdh, то выводится сообщение об уже установленном TSR.
  13. Если в обработчике прерывания int2f_handler значение регистра AX равно 0fcfdh, то выполняется установка TSR.
  14. После установки TSR выполняется обработка прерывания int9_handler.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4.2 из 5
Похожие ответы