lunes, 11 de mayo de 2015

Interrupciones en modo real

Interrupciones en modo real

Cuando se presiona una tecla se genera una interrupción de hardware. en este caso la interrupcion de hardware 09, la tabla de interrupciones esta a partir de la dirección de memoria 0x00, en la dirección 0x09 x 4 va estar el vector de interrupción que apunta a la rutina que atiende a la interrupción de teclado en este caso ¨keyhandler¨ .
Leemos el código de la tecla presionada "Scan code" no el código ascii, y lo imprimimos en pantalla.

El programa en assembler int.asm es el siguiente.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
[ORG 0x7c00]      ; add to offsets
   jmp start
 
   %include "print.inc"
 
start:   
   xor ax, ax   ; make it zero
   mov ds, ax   ; DS=0
   mov ss, ax   ; stack starts at 0
   mov sp, 0x9c00   ; 200h past code start
 
   mov ax, 0xb800   ; text video memory
   mov es, ax
 
   cli      ;no interruptions
   mov bx, 0x09   ;hardware interrupt #
   shl bx, 2   ;multiply by 4
   xor ax, ax
   mov gs, ax   ;start of memory
   mov [gs:bx], word keyhandler
   mov [gs:bx+2], ds ; segment
   sti
 
   jmp $      ; loop forever
 
keyhandler:
   in al, 0x60   ; get key data
   mov bl, al   ; save it
   mov byte [port60], al
 
   in al, 0x61   ; keybrd control
   mov ah, al
   or al, 0x80   ; disable bit 7
   out 0x61, al   ; send it back
   xchg ah, al   ; get original
   out 0x61, al   ; send that back
 
   mov al, 0x20   ; End of Interrupt
   out 0x20, al   ;
 
   and bl, 0x80   ; key released
   jnz done   ; don't repeat
 
   mov ax, [port60]
   mov  word [reg16], ax
   call printreg16
 
done:
   iret




port60   dw 0
 
   times 510-($-$$) db 0  ; fill sector w/ 0's
   dw 0xAA55        ; req'd by some BIOSes
;==========================================

El print.inc

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
;----------------------
dochar:
   call cprint         ; print one character
sprint:
   lodsb      ; string char to AL
   cmp al, 0
   jne dochar   ; else, we're done
   add byte [ypos], 1   ;down one row
   mov byte [xpos], 0   ;back to left
   ret
 
cprint:   
   mov ah, 0x0F   ; attrib = white on black
   mov cx, ax    ; save char/attribute
   movzx ax, byte [ypos]
   mov dx, 160   ; 2 bytes (char/attrib)
   mul dx      ; for 80 columns
   movzx bx, byte [xpos]
   shl bx, 1    ; times 2 to skip attrib
 
   mov di, 0        ; start of video memory
   add di, ax      ; add y offset
   add di, bx      ; add x offset
 
   mov ax, cx        ; restore char/attribute
   stosw              ; write char/attribute
   add byte [xpos], 1  ; advance to right
 
   ret
 
;------------------------------------
 
printreg16:
   mov di, outstr16
   mov ax, [reg16]
   mov si, hexstr
   mov cx, 4   ;four places
hexloop:
   rol ax, 4   ;leftmost will
   mov bx, ax   ; become
   and bx, 0x0f   ; rightmost
   mov bl, [si + bx];index into hexstr
   mov [di], bl
   inc di
   dec cx
   jnz hexloop
 
   mov si, outstr16
   call sprint
 
   ret
 
;------------------------------------
A este programa lo asemblamos con la siguiente linea de codigo:


$ nasm -o int.img int.asm

Para correrlo desde VirtualBox podemos hacer los pasos que se hicieron en la seccion Paso a Modo protegido  o genramos una maquina Virtual en sistema operativo seleccionamos


Luego vamos a la pestaña Storage y le agregamos un Floppy Disk




Para el Floppy Disk elegimos la imagen int.img ya generado arrancamos la Maquina Virtual


Aparecerá una pantalla negra y cuando presionemos una tecla se imprime el "Scan Code"



No hay comentarios:

Publicar un comentario