Menja del Reloj
Hola a ver si alguien me puede ayudar, nesecito realizar en ensamblador un programa que me muetre la hora y la fecha y que a la vez la pueda cambiarla.
Si alguien me puede facilitar informacion, le estaria muy agradecido.
Desde ya muchas gracias, y espero sus ayudas.
Claudio
Chile
Si alguien me puede facilitar informacion, le estaria muy agradecido.
Desde ya muchas gracias, y espero sus ayudas.
Claudio
Chile
.model small
.stack 100h
.data
hora db 8 dup(\\' \\')
db \\'$\\'
ascii macro
mov bl,10
div bl
add ah,48
add al,48
endm
.code
mov cx,seg etiqueta1
lea dx,etiqueta1
mov ax,0
mov ds,ax ;mueve a ds el offset de la direccion de interrupciones del reloj
mov si,1Ch*4 ;mueve a si el desplazamiento de la direccion de interrupciones del reloj
cli ;inhabilita las interrupciones
mov ds:[si],dx ;mueve a la direccion de los vectores de interrupcion
mov ds:[si+2],cx ;del reloj la direccion de la rutina a tratar
sti ;habilita las interrupciones
jmp residente ;salta a residente (carga el programa en el vector de interrupciones)
etiqueta1 proc ;subrutina que visualiza el reloj por pantalla
cli
pushf ;guarda todos los registros en pila
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
push ss
push sp
push bp
mov ax,seg hora ;mueve a ds la direccion efectiva de las variables del programa
mov ds,ax
mov ax,40h
mov es,ax ;mueve a es el offset de la direccion donde se captura la hora
mov si,6Ch ;mueve a si el desplazamiento de la direccion donde se captura la hora
mov ax,es:[si] ;mueve a ax y a dx el contenido del contador donde se captura la hora
mov dx,es:[si+2]
mov bx,32400 ;1 hora son 3600 segundos. si produce 18 interrupciones cada segundo, para saber los segundos
div bx ;hay que dividir ax y dx por 18*3600 (=32400*2)
sar ax,1 ;desplazamiento de un bit hacia la derecha (divide por 2)
sar dx,1
ascii ;en dx ya tenemos las horas, por lo que los convertimos a codigo ascii
mov cx,0b800h ;movemos a ds el offset de la direccion de memoria de pantalla
mov ds,cx
mov ds:[144],ah ;movemos a las posiciones correspondientes los caracteres en codigo ascii de las horas
mov ds:[146],al
mov ah,\\':\\'
mov ds:[148],ah
mov bx,1080 ;los minutos son 60*18=1080, por lo que el resto de las horas lo dividimos entre 1080
mov ax,dx
mov dx,0
div bx
ascii ;el resultado lo convierte en codigo ascii
mov ds:[150],al ;y lo pone en la direccion de memoria de pantalla correspondiente
mov ds:[152],ah
mov ah,\\':\\'
mov ds:[154],ah
mov bx,18 ;por ultiomo, para saber los segundos dividimos por 18
mov ax,dx
mov dx,0
div bx
ascii ;convertimos el resultado de la division en caracteres del codigo ascii
mov ds:[156],al ;y el resultado lo ponemos en las direcciones correspondientes de la memoria de pantalla
mov ds:[158],ah
pop bp ;saca todos los registros de la pila
pop sp
pop ss
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
sti
etiqueta2: ;etiqueta para mover la ultima direccion+1 de la subrutina que debe quedar residente
popf
iret ;retorno al programa
endp
residente:
lea dx,etiqueta2+1 ;interrupcion para dejar el programa residente
int 27h
end
.stack 100h
.data
hora db 8 dup(\\' \\')
db \\'$\\'
ascii macro
mov bl,10
div bl
add ah,48
add al,48
endm
.code
mov cx,seg etiqueta1
lea dx,etiqueta1
mov ax,0
mov ds,ax ;mueve a ds el offset de la direccion de interrupciones del reloj
mov si,1Ch*4 ;mueve a si el desplazamiento de la direccion de interrupciones del reloj
cli ;inhabilita las interrupciones
mov ds:[si],dx ;mueve a la direccion de los vectores de interrupcion
mov ds:[si+2],cx ;del reloj la direccion de la rutina a tratar
sti ;habilita las interrupciones
jmp residente ;salta a residente (carga el programa en el vector de interrupciones)
etiqueta1 proc ;subrutina que visualiza el reloj por pantalla
cli
pushf ;guarda todos los registros en pila
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
push ss
push sp
push bp
mov ax,seg hora ;mueve a ds la direccion efectiva de las variables del programa
mov ds,ax
mov ax,40h
mov es,ax ;mueve a es el offset de la direccion donde se captura la hora
mov si,6Ch ;mueve a si el desplazamiento de la direccion donde se captura la hora
mov ax,es:[si] ;mueve a ax y a dx el contenido del contador donde se captura la hora
mov dx,es:[si+2]
mov bx,32400 ;1 hora son 3600 segundos. si produce 18 interrupciones cada segundo, para saber los segundos
div bx ;hay que dividir ax y dx por 18*3600 (=32400*2)
sar ax,1 ;desplazamiento de un bit hacia la derecha (divide por 2)
sar dx,1
ascii ;en dx ya tenemos las horas, por lo que los convertimos a codigo ascii
mov cx,0b800h ;movemos a ds el offset de la direccion de memoria de pantalla
mov ds,cx
mov ds:[144],ah ;movemos a las posiciones correspondientes los caracteres en codigo ascii de las horas
mov ds:[146],al
mov ah,\\':\\'
mov ds:[148],ah
mov bx,1080 ;los minutos son 60*18=1080, por lo que el resto de las horas lo dividimos entre 1080
mov ax,dx
mov dx,0
div bx
ascii ;el resultado lo convierte en codigo ascii
mov ds:[150],al ;y lo pone en la direccion de memoria de pantalla correspondiente
mov ds:[152],ah
mov ah,\\':\\'
mov ds:[154],ah
mov bx,18 ;por ultiomo, para saber los segundos dividimos por 18
mov ax,dx
mov dx,0
div bx
ascii ;convertimos el resultado de la division en caracteres del codigo ascii
mov ds:[156],al ;y el resultado lo ponemos en las direcciones correspondientes de la memoria de pantalla
mov ds:[158],ah
pop bp ;saca todos los registros de la pila
pop sp
pop ss
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
sti
etiqueta2: ;etiqueta para mover la ultima direccion+1 de la subrutina que debe quedar residente
popf
iret ;retorno al programa
endp
residente:
lea dx,etiqueta2+1 ;interrupcion para dejar el programa residente
int 27h
end
