Rutina en ensamblador para medir velocidad de pulsaciones

Programa que implementa un medidor de velocidad de pulsaciones del teclado. En un tiempo fijo, estimado por el programador, se da la posibilidad al usuario de teclear lo más rápido posible. Finalizado el tiempo de referencia para la medición, se visualiza un mensaje del tipo.

Numero de pulsaciones por minuto: xxxxx
Tienes un nivel: bueno/medio/malo

PILA SEGMENT STACK ‘stack’
   db 128 dup(?)
PILA ENDS

DATOS SEGMENT
   flag       dw 0
   bcd       db 5 dup(?),10,13,’$’
   cuenta       dw 0
   gu_tec_cs       dw ?
   gu_tec_ip       dw ?
   gu_tic_cs       dw ?
   gu_tic_ip      dw ?
   contador_tec   dw 0
   cadena         db ‘Teclas pulsadas por minuto: ‘,’$’
   bajo         db ‘Tiene un nivel bajo’,10,13,’$’
   medio         db ‘Tiene un nivel medio’,10,13,’$’
   alto         db ‘Tiene un nivel alto’,10,13,’$’
DATOS ENDS

INTER SEGMENT at 0
   org 8*4
   tic_ip       dw ?
   tic_cs         dw ?
   org 9*4
   teclado_ip       dw ?
   teclado_cs      dw ?
INTER ENDS

CODIGO SEGMENT
    ASSUME CS:CODIGO,DS:DATOS,SS:PILA,ES:INTER
ppal proc far
         push ds
         xor ax,ax
         push ax

         mov ax,datos
         mov ds,ax
         mov ax,inter
         mov es,ax
         
         call cambiar_teclado
         call cambiar_temporizador
         
otro:      cmp flag,0
         je otro
         
         mov ax,contador_tec
         shr ax,1
         mov contador_tec,ax
            
         call restituye
         
         mov ah,9
         mov dx,offset cadena
         int 21h
         
         mov ax,contador_tec
         push ax
         mov ax, offset bcd
         push ax
         call to_bcd
         
         mov ax,contador_tec
         cmp ax,11
         jns buc_me_al
         mov dx,offset bajo
         jmp continue
buc_me_al:   cmp ax,21
         jns buc_alto
         mov dx,offset medio
         jmp continue
buc_alto:   mov dx,offset alto
continue:   mov ah,9
         int 21h         
         
         ret
ppal endp

cambiar_temporizador proc
         cli
         mov ax,tic_cs
         mov gu_tic_cs,ax
         mov ax,tic_ip
         mov gu_tic_ip,ax

         mov tic_ip,offset rutina_temporizador
         mov tic_cs,seg rutina_temporizador
         sti
         ret
cambiar_temporizador endp

cambiar_teclado proc
         cli
         mov ax,teclado_cs
         mov gu_tec_cs,ax
         mov ax,teclado_ip
         mov gu_tec_ip,ax

         mov teclado_ip,offset rutina_teclado
         mov teclado_cs,seg rutina_teclado
         sti
         ret
cambiar_teclado endp

restituye proc
         cli
         mov ax,gu_tic_cs
         mov tic_cs,ax
         mov ax,gu_tic_ip
         mov tic_ip,ax
         
         mov ax,gu_tec_cs
         mov teclado_cs,ax
         mov ax,gu_tec_ip
         mov teclado_ip,ax
         sti
         ret
restituye endp

rutina_teclado proc far
         cli
         push ax
         mov ax,contador_tec
         inc ax
         mov contador_tec,ax
         pop ax
eoi:      mov al,20h
         out 20h,al
         sti
         iret
rutina_teclado endp

rutina_temporizador proc far
         cli
         push ax
         mov ax,cuenta
         inc ax
         mov cuenta,ax
         cmp ax,1080      ;1080 tics, que son mas o menos un minuto de tiempo 18*60
         jne sigue
         mov flag,1
sigue:      pop ax
         mov al,20h ;eoi
         out 20h,al
         sti
         iret
rutina_temporizador endp

to_bcd proc
         cli
         push ax
         push bx
         push dx
         push bp
         push si
         push di

         mov bp,sp
         mov ax,10h[bp]
         mov di,0eh[bp]
         mov bx,5
         mov si,10
bucle:    xor dx,dx
         div si
         add dl,’0′
         dec bx
         mov [di][bx],dl
         jnz bucle

          mov dx,di
         add dx,bx
         mov ah,9
         int 21h

         pop di
         pop si
         pop bp
         pop dx
         pop bx
         pop ax
         sti
         ret 4
to_bcd endp
CODIGO ENDS
   END ppal

Quizá te interese...