Vintage – Desabilitando Ctrl+Alt+Suprimir en MS-DOS

A raíz de este post voy a dedicar unos post a sacar algunas curiosidades que me he encontrado en mi código antiguo de principios de los 90.

En este caso se trataba de evitar que el ordenador se reiniciara cuando pulsabamos Control+Alt+Suprimir … en Quick Basic creaba una librería QLB donde linkaba mis rutinas en ensablador de forma que podía llamar a funciones escritas en ensamblador.

La función en concreto interceptaba la interrupcion 09h, que era la que se llamaba cada vez que se pulsaba y soltaba una tecla (también se llamaba cuando se mantenía pulsada), comprobaba el estado del teclado para ver si la combinación de teclas era la correcta, si no era la correcta llamaba a la interrupción antigua, pero si era la correcta enviaba un acuse de recibo al teclado y terminaba la interrupción con Iret, este es el código:

;InstallFlag es distinto de cero para instalar el TSR o cero para 
;desinstalarlo.
 
 
.Model Medium, Basic
.Code
Public Tsr
Tsr Proc Uses DS, InstallFlag:Word
 
  Cmp  InstallFlag,0  ;¿ quieren instalar la rutina ?
  Je   Deinstall      ;no, ir a desinstalar
 
  Cmp  CS:Old9Seg,0   ;sí, ¿ pero la hemos instalado ya ?
  Jne  Salida         ;sí, ¡ y no hay que hacerlo de nuevo !
 
  Mov  AX,3509h       ;preguntamos al DOS por la dirección del      
                      ;vector Int 9
  Int  21h            ;el DOS devuelve el segmento:direccion en     
                      ;ES:BX
  Mov  CS:Old9Dir,BX  ;lo guarda de forma local
  Mov  CS:Old9Seg,ES
 
  Mov  AX,2509h       ;apunta Interrrupt 9 a nuestro controlador
  Mov  DX,Offset NewInt9
  Push CS             ;copia CS en DS
  Pop  DS
  Int  21h
 
Salida:
  Ret                 ;vuelve al BASIC
 
 
;-- El controlador viene aquí cada vez que se pulsa o se libera una 
;tecla.
NewInt9:
  Sti             ;habilita futuras interrupciones
  Push AX         ;guarda los registros que vamos a usar
  Push DS
 
  In   AL,60h     ;obtiene el código de barrido del teclado
  Cmp  AL,83      ;¿ es la tecla Del ?
  Jnz  Continua   ;no, sigue en la interrupción 9 del BIOS 
 
  Xor  AX,AX      ;mira si están pulsadas las teclas Alt y Control 
  Mov  DS,AX      ;en la dirección 0:417h
 
  Mov  AL,DS:[417h]  ;obtiene el estado de desplazamiento en        
                     ;0000:0417h
  Test AL,8      ;¿ esta pulsada la tecla Alt ?
  Jz   Continua  ;no, sigue en la interrupción del BIOS 
  Test AL,4      ;¿ está pulsada la tecla Control ?
  Jz   Continua  ;no, sigue en la interrupción del BIOS 
 
  Mov Ax, 30
  Mov 0:[41Ah], Ax
  Mov Ax, 32
  Mov 0:[41Ch], Ax
  Mov Ah, 44
  Mov Al, 0
  Mov 0:[41Eh], Ax
 
  In   AL,61h    ;envía un acuse de recibo al teclado
  Mov  AH,AL     ;caso contrario la pulsación Control-Alt-Del 
  Or   AL,80h    ;  estaría allí la siguiente vez que un
  Out  61h,AL    ;  programa obtuviera una tecla
  Mov  AL,AH
  Out  61h,AL
  Mov  AL,20h    ;indica el final de la interrupción al chip 
  Out  20h,AL    ;  8259 que controla la interrupción
 
  Pop  DS        ;lo ignora, y simplemente vuelve al llamante
  Pop  AX
  Iret           ;usa esta forma especial de la instrucción Ret
                 ;  cuando vuelve de una rutina de interrupción
 
Continua:
  Pop  DS        ;restaura los registros guardados
  Pop  AX
  Jmp  DWord Ptr CS:Old9Dir   ;sigue en la interrupción 9 del BIOS
                              ;  saltando a la dirección que se 
                              ;  grabó en la inicialización
 
DeInstall:
  Mov  AX,2509h          ;restaura el controlador Int 9 original
  Mov  DX,CS:Old9Dir     ;desde el segmento y la dirección          
                         ;guardadas anteriormente
  Mov  DS,CS:Old9Seg
  Int  21h               ;el DOS lo hace en nuestro lugar
  Mov  CS:Old9Seg,0      ;borra esto para indicar que no está       
                         ;instalado
  Jmp  Short Salida      ;y luego vuelve al BASIC
 
Tsr Endp
 
  Old9Dir   DW 0   ;esto recuerda la dirección de Int 9 original
  Old9Seg   DW 0   ;debe estar en el segmento de código porque 
                   ;  DS no está definido cuando NewInt9 toma el control
End

Los comentarios son originales, en aquellos entonces el ASM lo controlaba lo justo y comentaba todo para luego acordarme de lo que hacía.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

Demuestra que no eres un bot *