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 ;------------------------------------ |
$ 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"