Академический Документы
Профессиональный Документы
Культура Документы
PROGRAMA TECLADO1
Segmento de datos, en l definimos la tabla llamada fila con la que colocaremos el texto
en pantalla : cdigo ASCII
Rastreador y debajo de este texto iremos
colocando los cdigos de las teclas que vayamos pulsando.
datos segment
fila db "codigo ASCII
tecla db ?
datos ends
Rastreador$"
Con el servicio 00h de la interrupcin 16h, hago que el procesador espere a recibir una
pulsacin de una tecla en el teclado, cuando esto ocurre, carga el valor del cdigo ASCII
en AL y el del rastreador en AH
pepe: mov ah,00h
int 16h
Guardo AX en la pila ya que al entrar en la macro mostrarcodigo para mostrar el codigo
ascii correpondiente al carcter pulsado, voy a variar su contenido, pero luego lo necesito
otra vez tal y como estaba para entrar de nuevo en la macro mostrarcodigo para mostrar
el cdigo del rastreador.
push ax
Comparo el contenido del cdigo ascii de la ltima tecla pulsada con el valor 13 que es el
correspondiente al ENTER, si son iguales salto a la etiqueta fin, y si no lo0 son vuelvo a la
etiqueta pepe
cmp tecla,13
je fin
jmp pepe
mov ax,4c00h
int 21h
ejemplo endp
codigo ends
1 INGENIERA TCNICA EN INFORMTICA DE GESTIN EUITI VITORIA
Profesor : Fernando Oterino Echvarri
MACRO MOSTRARCODIGO
Con esta macro pretendo mostrar en pantalla el contenido del registro AL, no el
codigo ASCII correspondiente a ese valor.
Definicin de la macro mostrarcodigo con el parmetro sitio que indica el numero de
columna de la pantalla donde se escribir.
MOSTRARCODIGO MACRO sitio
Definicin local de las variables utilizadas en esta macro
LOCAL LETRA,MUESTRA,LET2,MUEST2
Guardo los registros en la pila, para que antes de salir los pueda recuperar tal y como
estaban antes de entrar
PUSH DX
PUSH CX
PUSH BX
PUSH AX
Para mostrar la cifra que tengo en AL, necesito separar los dos nibbles de este registro,
ya que cada uno de ellos formar una cifra hexadecimal, para coger slo el nibble 0 hago
la operacin AND lgica entre el registro AL y el valor inmediato 0F.
AND AL,0FH
Ahora en AL slo tengo dato en el nibble 0, en caso de tener un valor entre 0 y 9 y como
voy a usar el servicio 0Ah de la interrupcin 10h para mostrarlo en pantalla, tendr que
sumarle 30 para que muestre la cifra entre 0 y 9 correspondiente. Es decir, si tengo un
0010 que es un nmero 2, debo cargar AL con el cdigo ASCII correspondiente a ese 2,
este cdigo es el 32h, y lo mismo para el resto de cifras entre 0 y 9, as que si el
contenido del nibble 0 de AL est entre 0 y 9 le sumo 30h.
Pero si el valor del nibble 0 de AL est entre 0Ah y 0Fh, le tengo que sumar 37h, ya que
por ejemplo 0Ah + 37h = 41h que es el cdigo ASCII de la A.
Lgicamente slo le sumaremos una cantidad, 30h o 37h segn el contenido del nibble 0
de AL est entre 0 .. 9 o entre A ... F.
CMP AL,0AH
JAE LETRA
ADD AL,30H
JMP MUESTRA
LETRA:
ADD AL,37H
Coloco el cursor en la columna indicada por el parmetro sitio, fila 10 y pgina cero.
MUESTRA:PAMCUR sitio,10,0
Mediante el servicio 0Ah de la interrupcin 10h escribo el contenido de AL en la posicin
actual del cursor de la pgina 0
mov ah,0ah
mov bh,00h
mov cx,0001h
int 10h
Antes de entrar tena en AL el valor que quera mostrar, ya he mostrado el nibble 0, ahora
recupero AX de la pila para realizar la misma operacin con el nibble 1 o superior, antes
de hacer nada lo vuelvo a guardar para recuperarlo al final de la macro
POP AX
PUSH AX
Anlogo al caso del nibble inferior, hago la AND lgica esta vez con F0h para aislar el
nibble superior
AND AL,0F0H
Para actuar de la misma forma que con el nibble inferior, debo convertir mi nibble superior
en inferior, para ello desplazo los bits 4 veces hacia la derecha.
MOV CL,04H
SHR AL,CL
Esta parte es igual que la comentada en el nibble inferior
CMP AL,0AH
JAE LET2
ADD AL,30H
JMP MUEST2
LET2: ADD AL,37H
Esta parte es igual que la comentada en el nibble inferior, pero en este caso escribiremos
una columna a la izquierda de donde he escrito antes.
MUEST2:
PAMCUR sitio-1,10,0
mov ah,0ah
mov cx,0001h
int 10h
Recupero los registros de la pila y finalizo la macro
POP AX
POP BX
POP CX
POP DX
ENDM
PROGRAMA TECLADO2
Segmento de datos con un byte reservado para almacenar los segundos que leo del
sistema con el servicio 21h de la interrupcin 10h
Datos segment
segundos db ?
datos ends
Comienzo del segmento de cdigo incluyendo los ficheros pamcur.asm y macro3.asm e
inicio del procedimiento principal llamado ejemplo.
codigo segment para
assume cs:codigo,ss:pila,ds:datos
include pamcur.asm
INCLUDE MACRO3.ASM
ejemplo proc far
Inicializacin del segmento de datos
mov ax,datos
mov ds,ax
El registro AL lo voy a usar para ir contando segundos, para esto me aseguro que al
principio est a cero y lo guardo en la pila
mov al,00h
push ax
Cargo la tabla segundos del segmento de datos con el valor de los segundos actuales,
con ello podr saber cuando aumentan los segundos y con ello aumentar el contador AL
mov ah,2ch
int 21h
mov segundos,dh
Coloco el modo de video en 80 X 25 Alfanumrica y color
mov ax,0003h
int 10h
Uso el servicio 01h de la interrupcin 16h para dos cosas, primero para saber si se ha
pulsado o no una tecla, y en el caso de haber pulsado una tecla los cdigos de esta se
cargan en AH y en AL como con el servicio 00h de esta misma interrupcin, pero la
diferencia es que con este servicio el programa no se me para aqu, y adems el servicio
00h no afectaba a ZF indicando si se haba pulsado una tecla, es decir, quedaba el
programa parado hasta que se pulsase una tecla, cosa que no ocurre con este servicio
vuelta:
mov ah,01h
int 16h
Si ZF = 1 quiere decir que el buffer del teclado est vaco, lo que implica que no se ha
pulsado tecla alguna, por lo que ir a la etiqueta seguir, en caso contrario se ejecutarn
las dos siguientes instrucciones finalizando la ejecucin del programa
jz seguir
Instrucciones de finalizacin del programa
mov ax,4c00h
int 21h
Con el servicio 2Ch de la interrupcin 21h, leo la hora actual del sistema
seguir:
mov ah,2ch
int 21h
Comparo los segundos actuales (DH) con los ltimos almacenados en el segmento de
datos, si son iguales es que no ha pasado un segundo, por lo que salto a vuelta para ver
si se ha pulsado una tecla
cmp dh,segundos
je vuelta
En el caso de que realmente los segundos han cambiado, recupero el valor de al y le
sumo una unidad convirtiendo el resultado a decimal.
pop ax
add al,01h
daa
Comparo AL con 60, en el caso de que sea menor, guardo AX en la pila, pero si es igual
o mayor lo pongo a cero antes de guardar.
cmp al,60h
jb lolu
mov al,00h
lolu: push ax
PROGRAMA TECLADO3
Para saber cuando debo de salir del programa, tengo que chequear si se ha pulsado una
tecla, y en el caso de que esa tecla pulsada sea la de enter saldr del programa, pero no
quiero esperar hasta que se pulse una tecla, lo que quiero es seguir mostrando las
variaciones de KB_FLAG hasta que se pulse ENTER.
Si leo el teclado con el servicio 00h de la interrupcin 16h, el programa se detendr a la
espera de tener algo en el buffer del teclado, y eso no es lo que se pretende, por ello
usar el servicio 01h para saber si hay algn carcter esperando en el buffer del teclado,
y en ese caso leer ese carcter con el servicio 00h de la interrupcin 16h.
Se puede pensar que este ltimo paso no es necesario, ya que el servicio 01h de la
interrupcin 16h tambin me devuelve los cdigos de la tecla pulsada, pero tiene la
desventaja en este caso de que no vaca el buffer del teclado, en ese caso estara todo el
rato mostrando la primera tecla pulsada, y si no es ENTER nunca se acabara el
programa
10
Mediante el servicio 01h de la interrupcin 16h leo el estado del buffer si el buffer tiene
dato colocar ZF = 0 y en caso contrario a 1
mov ah,01h
int 16h
En el caso de que el buffer del teclado no estuviera vaco, ( se ha pulsado una tecla (ZF =
0) uso jnz para saltar a la etiqueta vuelta4 en la que recoger ese dato en AX y lo
mostrar en pantalla, si no se produce este salto, iremos de vuelta a la etiqueta
VUELTA para seguir recogiendo el contenido de KB_FLAG.
Se puede pretender sustituir estas dos instrucciones por una sola JZ vuelta, pero el
salto excede del mximo salto permitido para los saltos condicionales
jnz vuelta4
jmp vuelta
Leo el cdigo de la tecla pulsada con el servicio 00h de la interrupcin 16h y lo muestro
en pantalla.
vuelta4:
mov ah,00h
int 16h
mostrarcodigo 21h
Comparo el cdigo ASCII de la tecla pulsada con 13 que es el correspondiente a ENTER,
en el caso que se haya pulsado ENTER, saltar a la etiqueta vuelta3 donde est el
cdigo de finalizacin del programa, en caso contrario, volver hacia arriba a leer de
nuevo el estado de KB_FLAG en la etiqueta vuelta
Se puede pretender sustituir estas dos instrucciones de salto por una sola JNE vuelta,
pero el salto excede del mximo salto permitido para los saltos condicionales
cmp al,13
je vuelta3
jmp vuelta
A esta etiqueta se llegar si se pulsa ENTER en cualquier momento, en ese caso
finalizamos el programa con el servicio 4Ch de la interrupcin 21h y cerramos el
procedimiento principal.
vuelta3:
mov ax,4c00h
int 21h
ejemplo endp
Finalizacin del segmento de cdigo, Escribo el segmento de pila y finalizo el programa
indicando el procedimiento principal.
codigo ends
pila segment para stack
dw 512 dup (?)
pila ends
end ejemplo
11
PROGRAMA TECLADO4
12
Este mismo programa se puede realizar con los servicios 07h y 08h con la diferencia es
que estos servicios no muestras la tecla pulsada, en ese caso slo veramos el contador,
adems la diferencia entre ambos servicios consiste en que el servicio 07h no responde a
pulsaciones de CTRL+Break y el 08 si lo hace
13
PROGRAMA TECLADO6
14
Para utilizar el servicio 0ah de la interrupcin 21h del DOS, tengo que cargar en DS:DX la
direccin del segmento de datos de la tabla en la que voy a escribir la cadena de
caracteres, el primer byte ser el nmero mximo de caracteres que se pueden escribir, y
en el segundo byte quedara memorizado el numero de bytes escritos (nmero de teclas
pulsadas) despus de presionar ENTER. Los caracteres ASCII tecleados quedarn a
partir del tercer byte.
lea dx,tabla
mov ah,0ah
int 21h
La posicin donde estar el ENTER ser la del comienzo de la tabla que he rellenado
tecleando caracteres la tendr que calcular de la siguiente forma, (Offset de comienzo de
la tabla + nmero de caracteres tecleados + 2 (los dos primeros bytes estn reservados
con el nmero mximo de caracteres y con el nmero de caracteres tecleados)
Para realizar el clculo comentado, necesito saber cuanto caracteres han sido tecleados,
esta informacin la tengo en el segundo byte de la tabla y lo leo con la funcin XLAT
quedando ese valor en AL. Al hacer esto tambin me queda en BX el offset de comienzo
de la tabla.
Lea bx,tabla
mov al,01
xlat tabla
Ahora debo sumar AL + BX + 2, pero no puedo sumar AL+BX, porque son de diferente
tamao, as que tengo que sumar AX + BX, por ello me aseguro que AH = 00 y al
resultado de la suma de AX y BX le sumo 2
mov ah,00h
add bx,ax
add bx,02h
Cargo el carcter $ en la posicin del segmento de datos calculada.
mov al,"$"
mov ds:[bx],al
Coloco el cursor el la fila y columna 12 de la pgina 0
pamcur 12,12,0
15
Para utilizar el servicio 09h de la interrupcin 21h que muestra en pantalla una cadena de
caracteres finalizada en $, tengo que cargar en DX el Offset donde comienzan dichos
caracteres, ste ser el offset de comienzo de la tabla + 2
Lea dx,tabla
add dx,2
mov ah,09h
int 21h
Cdigo de finalizacin del programa
mov ax,4c00h
int 21h
Final del procedimiento principal y del segmento de cdigo
tec1 endp
codigo ends
Segmento de pila y finalizacin del programa
pila segment para stack
dw 512 dup (?)
pila ends
end tec1
16
PROGRAMA CURSOR
17
18
Si la tecla pulsada ha sido la D, llamo a la macro mover con parmetros col = +1 y fil =
0, en caso contrario salto a la etiqueta sig1
cmp al,"D"
jne sig1
mover +1,0
Si la tecla pulsada ha sido la I, llamo a la macro mover con parmetros col = -1 y
fil = 0, en caso contrario salto a la etiqueta sig2
sig1: cmp al,"I"
jne sig2
mover -1,0
Si la tecla pulsada ha sido la B, llamo a la macro mover con parmetros col = 0 y
fil = +1, en caso contrario salto a la etiqueta sig3
sig2: cmp al,"B"
jne sig3
mover 0,+1
Si la tecla pulsada ha sido la A, llamo a la macro mover con parmetros col = 0 y
fil = -1, en caso contrario salto a la etiqueta otra
sig3: cmp al,"A"
jne otra
mover 0,-1
Vuelvo a la etiqueta vuelta para esperar que se pulse otra tecla
otra: jmp vuelta
Final del procedimiento cursor y del segmento de codigo
cursor endp
codigo ends
Segmento de pila y finalizacin del programa.
pila segment para stack
dw 512 dup (?)
pila ends
end cursor
19
PROGRAMA CURSOR2
Modificar el programa anterior para que el movimiento se haga con las flehas
del teclado.
El programa finalizar al pulsar la tecla ESC
Igual al programa cursor.asm, sustituyendo las referencias a las teclas D,I,A,B por las
flechas
codigo segment para
assume cs:codigo,ss:pila
include pamcur.asm
escribir macro carac
mov ah,0ah
mov bh,0
mov cx,0001h
mov al,carac
int 10h
endm
mover macro col,fil
escribir " "
mov ah,03h
mov bh,00h
int 10h
add dl,col
add dh,fil
pamcur dl,dh,0
escribir ""
endm
cursor proc far
mov ax,0003h
int 10h
pamcur 35,12,0
escribir ""
Para leer la tecla pulsada uso el servicio 00h de la interrupcin 16h, que me devuelve en
AH el cdigo rastreador de las teclas pulsadas
vuelta:
mov ah,00h
int 16h
20
Igual que en el programa cursor.asm pero ahora comparo el cdigo rastreador de las
flechas del teclado.
Flecha Derecha = 4Dh
Flecha Izquierda = 4Bh
Flecha Abajo = 50h
Flecha Arriba = 48h
cmp ah,4dh
jne sig1
mover +1,0
sig1: cmp ah,4bh
jne sig2
mover -1,0
sig2: cmp ah,50h
jne sig3
mover 0,+1
sig3: cmp ah,48h
jne otra
mover 0,-1
Si el cdigo rastreador de la tecla pulsada es la correspondiente a la tecla ESC (01h),
salto a la etiqueta salir donde he colocado el cdigo de finalizacin del programa. En caso
contrario volver a esperar la pulsacin de otra tecla.
otra: cmp ah,01h
je salir
jmp vuelta
salir: mov ax,4c00h
int 21h
Igual que en cursor.asm
cursor endp
codigo ends
pila segment para stack
dw 512 dup (?)
pila ends
end cursor