1- Descripcion del Problema
El programa lee la fecha del sistema y la muestra en consola. Muestra la fecha de hoy y la de los próximos 7 días.
2- Problemas Encontrados
Los problemas encontrados fueron los que se espera encontrar al ser la primera vez que se programa algo en el lenguaje ensamblador: Encontré problemas al utilizar los ciclos, al utilizar las instrucciones básicas, al usar las interrupciones y al intentar imprimir datos en la pantalla.
Primero tuve que ir hasta la biblioteca a conseguir el libro
para poder empezar, luego de buscar lo mismo por varias horas en internet.
Consiguiendo el libro me dispuse a aprender a ensamblar, pero resultó más
difícil de lo que creía. El problema parece fácil a primera vista pero después
de ponerse a intentar usar los registros y no perderles rastro se complica
bastante
Parte importante de el programa es el uso de las interrupciones de DOS. Las más usadas fueron la 2Ah y la 02h: la primera da la fecha actual del sistema, la da en varios registros y tuve que hacer bastantes cambios para poder poner correctamente la fecha para imprimir. La segunda imprime un caracter ASCII en la pantalla, el principal problema con esta es el hecho de que la fecha está dada en números hexadecimales, tuve que idear la forma de pasar estos números a el formato ASCII.
3- Detalles de implementación:
El principal problema que pude resolver, pero no implementar adecuadamente, fue el de imprimir un número de dos dígitos en formato ASCII.:
IMPRIMIR SEGUN FRAN.
Se pone el entero de dos dígitos que se quiera imprimir en el registro BX. El
método le da vuelta con un ROL se imprime lo que haya en AH como un caráter
ASCII.
AX|0|0|3|1|=>ROL=>|0|3|1|0|=>imprimirAH(3)=>BORRARAH=>|0|0|1|0|=>ROL=>|0|1|0|0|=>imprimirAH=1=>Salida=31
.MODEL SMALL
.STACK 64
.DATA
day DB (?)
month DB (?)
year DW (?)
CICLE DW (?)
.CODE
MAIN PROC NEAR
MOV AX, @data
MOV DS, AX ; Inicializo segmento de datos.
MOV CX, 07h ; número de veces que se repite el ciclo.
PUSH CX ;Guarda CX para el ciclo.
MOV AH, 2AH
INT 21H ; Fecha/hora del sistema.
MOV DAY, DL
MOV MONTH, DH
MOV YEAR, CX
ciclo:
CMP DAY, 32H
JNE dia
Mov DAY, 01H
dia:
XOR AX, AX
;El día se almacena en el registro DL.
MOV AL, DAY ;Imprime el día
CALL ImprimirEntero
MOV DL, 2Fh ;Pone un '/' después de el día.
MOV AH, 02H
INT 21H
CMP MONTH, 13 ;Si el mes es 12
JNE mesaño
MOV MONTH, 01
INC YEAR
mesaño:
XOR AX, AX
;El día se almacena en el registro DL.
MOV AL, MONTH ;Imprime el día
CALL ImprimirEntero
MOV DL, 2FH ;;Pone un '/' después de el mes.
MOV AH, 02H
INT 21H
;El año es un número binario igual a 1980 hasta 2099.
;Se almacena en el registro CX ==>2006->CH =07,CL =D6.
MOV AX, YEAR ;Pone el año y lo imprime.
CALL ImprimirEntero
MOV DL, 0AH ;Deja un renglón en blanco.
MOV AH, 06H
INT 21H
INC DAY
POP CX
LOOP ciclo
;----------------------------------------------------------------------------------------------------
MOV AH, 4CH ; Salir al DOS.
INT 21H
MAIN ENDP
ImprimirEntero PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX ; Guarda registros
; bandera
MOV CX, 1
; el resultado de dividir entre 10000 siempre <= 9
MOV BX, 10000 ; 2710h - divider.
CMP AX, 0 ; AX es un cero?
JZ imprimeCero ; Sí, entonces imprímalo
imprima: ; No, entonces procese el número
CMP BX,0 ; Si BX==0, es porque ya terminó!
JZ termine
; evita imprimir ceros antes del número
CMP CX, 0
JE calc
CMP AX, BX ; Si AX<BX, resultado de la div. será cero.
JB salte ; entonces puede calcular BX/10
calc:
MOV CX, 0 ; bandera
MOV DX, 0
DIV BX ; AX = DX:AX / BX
; Imprime el último dígito
; AH siempre es cero
ADD AL, 30h ; convertir al código ascii
MOV AH, 0Eh
INT 10h
MOV AX, DX ; obtiene el residuo de la última división
salte:
; Calcula BX=BX/10
PUSH AX
PUSH CX
MOV DX, 0
MOV AX, BX ; AX = DX:AX / 10
MOV CX, 10
DIV CX
MOV BX, AX
POP CX
POP AX
JMP imprima
imprimeCero:
MOV AL, '0'
MOV AH, 0Eh
INT 10h
termine:
POP DX
POP CX
POP BX
POP AX
RET
ImprimirEntero ENDP
END MAIN