Thorax
Power Member
Alarme + Relogio Assembly
Caros amantes de Assembly ou nao.. lol (isto de programar assembly realmente nao tem mesmo nada a ver que programar Visual c++ ou basic ate mesmo pascal...) mas o que é verdade e que tenho uma cadeira em que tenho de fazer um trabalho em assembly e que consiste em colocar as horas do relogio mais a data no monitor e também fazer um Alarme ou seja quando as horas do sistema coicidirem com as horas do Alarme entao dispara uma mensagem de alerta. acho que ate aqui ninguem tem duvidas nem eu. Este programa so pode ser executado em MS DOS porque é o SO que nao tem seguranças e que podemos mexer em tudo e mais alguma coisa no sistema que o DOS nao se importa.
O que acontece que ja tenho o Codigo feito so que tenho um problema e que quando chega a altura de introduzir a hora e minutos do alarme (HHmm) mesmo antes de conseguir introduzir ele bloqueia-me o sistema operativo. Ok probavelmente tenho algum registo que estou a mexer e que estou a fazer para bloquear o OS mas o problema e saber qual é mesmo esse registo (ou talves nao seja)
NOTA: Estou a utilizar o REal time clock do sistema.
Pois bem aqui apresento-vos o meu algoritmo.
Algoritmo Principal
1º Colocar o endereço da rotina int4a no vector interrupt 4aH
2º Colocar o endereço da rotina int1c no vector interrupt 1CH
3º Perguntar a Hora do Alarme
4º Configurar o Real Time Clock
5º Tornar este programa Residente
Algoritmo para a Rotina do Atendimento ao Interrupt 1Ch
1º Ler Hora
2º Converter a Hora de BCD para ASCII
3º Escrever a Hora
4º Ler Minutos
5º Converter os Minutos de BCD para ASCII
6º Escrever os Minutos
7º Ler Segundos
8º Converter os Segundos de BCD para ASCII
9º Escrever os Segundos
10º Ler Dia
11º Converter os Dia de BCD para ASCII
12º Escrever Dia
13º Ler Mês
14º Converter Mês de BCD para ASCII
15º Escrever Mês
16º Ler Ano
17º Converter Ano de BCD para ASCII
18º Escrever Ano
Algoritmo para a Rotina do Atendimento ao Interrupt 4aH
1º Dispara uma mensagem de Alerta.
O Codigo Fonte é o Seguinte:
.486
cseg segment use16
main proc far
assume cs:cseg
mov dx, offset int1c
mov ax, seg int1c
mov ds,ax
mov ah,25h
mov al,1ch
int 21h ;coloca o endereço da rotina int4a no vector de interrupt 4AH
mov dx, offset int4a
mov ax, seg int4a
mov ds,ax
mov ah,25h
mov al,4ah
int 21h ;Coloca o endereço da rotina int1ch no vector de interrup 1CH
;/////////////////////////////////////////////////////////////////////////////////
;DEFENIR O FORMATO A TRABALHAR (BCD)
mov al,0bh
out 70H,al
in al,71h
and al,11111011B
out 71H,al
;/////////////////////////////////////////////////////////////////////////////////
;--->Perguntar a Hora do Alarme
mov ah,1 ;;Fica a espera que o utilizador prime numa tecla
int 21H
sub al,'0' ;;Converte o codigo ASCII em binario
mov bl,al ;;Coloca o valor de al no bl
shl bl,4 ;;Converte o codigo binario para BCD
mov ah,1 ;;Fica a espera que prime outra tecla
int 21H
sub al,'0'
add bl,al ;; 12 d = 0001 0010 bcd
;Acrescentar a Hora ao Real Time Clock
mov al,05H
out 70H,al ;;Coloquei a hora do formato BCD no
mov al,bl ; ;Real Time Clock corresondente as
out 71H,al ;; horas do Alarme = 05H
;Perguntar os Minutos do Alarme
mov ah,1 ;;Fica a espera que o utilizador prime numa tecla
int 21H
sub al,'0' ;;Converte o codigo ASCII em binario
mov bl,al ;;Coloca o valor de al no bl
shl bl,4 ;:Converte o codigo binario para BCD
mov ah,1 ;;Fica a espera que prime outra tecla
int 21H
sub al,'0'
add bl,al ;; 12 d = 0001 0010 bcd
;Acrescentar os minutos ao Real Time Clock
mov al,03H
out 70H,al ;;Coloquei os minutos do formato BCD no
mov al,bl ;; Real Time Clock corresondente as
out 71H,al ;; horas do Alarme = 05H
;Defenir os Segundos do Alarme
mov bl,00000000
;Neste ultimo caso, o codigo BCD de 0 e igual ao binario
;Acrescentar os segundos ao Real Time Clock
mov al,01H
out 70H,al ;;Coloquei os segundos do formato BCD no
mov al,bl ;; Real Time Clock corresondente as
out 71H,al ;; horas do Alarme = 01H
;--->Configurar o Real Time Clock
;Colocar o Bit 5 e 6 do Status B a 1
mov al,0bH
out 70H,al ;; Activamos o Interrupt do Alarme
in al,71H ;; Activamos o Interrupts Periodicos
mov al,01100010B
out 71H,al
;IR ao Interrupt Mask Register e garantir k nao esta MASCARADO IRQ8 =A1H
in al,0a1h
and al,11111110B
out 0a1h,al
mov dx,zseg
mov ax,es
sub dx,ax ;determina o numero de paragrafos para deixar em memoria
mov ah,31h
int 21h ;termina o programa deixando o residente em memoria
main endp
;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int1c proc far ; rotina de atendimento ao interrupt
push ax
push bx
push cx
push di
push es ;faz o push de todos os registos que utiliza
;--->CRiar uma Subrotina Converte
converte proc far
mov bl, al
shr al, 4
add al,'0'
mov es:[di], ax
add di, 2
mov al, bl
and al, 00001111b
add al, '0'
mov es:[di], ax
add di, 2
ret
converte endp
;--->LER HORA
mov al, 04h ;coloca o valor das horas no registo al
in al, 71h ;le o que esta em 71h e coloca-lo no registo al
;--->Converte a hora de BCD para ASCII
Call converte
;--->Escreve Hora
out 70h, al ;escreve o que esta no registo al e coloca-lo no ;endereço indicado por 70h
;--->LER Minutos
mov al, 02h ;coloca o valor dos minutos no registo al
in al, 71h ;le o que esta em 71h e coloca-lo no registo al
;--->Converte a minutos de BCD para ASCII
Call converte
;--->Escreve Minutos
out 70h, al ;escreve o que esta no registo al e coloca-lo no ;endereço indicado por 70h
;--->LER segundos
mov al, 00h ;coloca o valor das segundos no registo al
in al, 71h ;le o que esta em 71h e coloca-lo no registo al
;--->Converte a segundos de BCD para ASCII
Call converte
;--->Escreve segundos
out 70h, al ;escreve o que esta no registo al e coloca-lo no ;endereço indicado por 70h
;--Posiçao da memoria video que queremos posicionar o cursor-----------------------------------------------------------------------------------
Mov di, 200 ; Coloca no offset o valor 200 (valor da posiçao de memoria video em que queremos que apareça o cursor)
;----------------------------------------------------------------------------------------------------------------------------------------------
;--->LER dia
mov al, 07h ;coloca o valor do Dia no registo al
in al, 71h ;le o que esta em 71h e coloca-lo no registo al
;--->Converte o dia de BCD para ASCII
Call converte
;--->Escreve dia
out 70h, al ;escreve o que esta no registo al e coloca-lo no ;endereço indicado por 70h
;--->LER Mes
mov al, 08h ;coloca o valor do mes no registo al
in al, 71h ;le o que esta em 71h e coloca-lo no registo al
;--->Converte a mes de BCD para ASCII
Call converte
;--->Escreve mes
out 70h, al ;escreve o que esta no registo al e coloca-lo no ;endereço indicado por 70h
;--->LER ANO
mov al, 09h ;coloca o valor do ano no registo al
in al, 71h ;le o que esta em 71h e coloca-lo no registo al
;--->Converte o ano de BCD para ASCII
Call converte
;--->Escreve ano
out 70h, al ;escreve o que esta no registo al e coloca-lo no ;endereço indicado por 70h
pop es
pop di
pop cx
pop bx
pop ax ; restaura todos os registos usados
iret ; termina a rotina de interrupt
int1c endp
;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
mesg db 'ALARME!! ALARME!! ALARME!! ALARME!!$'
int4a proc far ; rotina de atendimento ao interrupt
push ax
push bx
push cx
push di
push es ;faz o push de todos os registos que utiliza
;Definir um ponteiro de leitura
mov ax,0B800H
mov es,ax
mov di,0
;Definir um ponteiro de escrita
mov ax,seg mesg
mov ds,ax
mov si,offset mesg
;Ler o character do ponteiro de leitura
lb2: mov al, ds:[si]
;Comparar com '$'
Cmp al, '$'
;Se não for igual Escreve o carácter no ponteiro de escrita
JE Fim
mov es:[di],al
;Actualizar o ponteiro de escrita e de leitura
inc si
add di, 2
Jmp lb2
; Se for igual ao dólar terminar
Fim: pop es
pop di
pop cx
pop bx
pop ax ; restaura todos os registos usados
iret ; termina a rotina de interrupt
int4a endp
cseg ends
zseg segment use16
zseg ends ; segmento para calcular o tamanho do programa
end
OS programas que utilizo é o TASM + o LINK e depois para ver a execuçao linha a linha utilizo o Turbo DEbuguer.
SErá que alguem me pode ajudar com a parte do codigo?MAs porque que ele me Crasha? é essa a minha pergunta
Agradeço a vossa ajuda.
Caros amantes de Assembly ou nao.. lol (isto de programar assembly realmente nao tem mesmo nada a ver que programar Visual c++ ou basic ate mesmo pascal...) mas o que é verdade e que tenho uma cadeira em que tenho de fazer um trabalho em assembly e que consiste em colocar as horas do relogio mais a data no monitor e também fazer um Alarme ou seja quando as horas do sistema coicidirem com as horas do Alarme entao dispara uma mensagem de alerta. acho que ate aqui ninguem tem duvidas nem eu. Este programa so pode ser executado em MS DOS porque é o SO que nao tem seguranças e que podemos mexer em tudo e mais alguma coisa no sistema que o DOS nao se importa.
O que acontece que ja tenho o Codigo feito so que tenho um problema e que quando chega a altura de introduzir a hora e minutos do alarme (HHmm) mesmo antes de conseguir introduzir ele bloqueia-me o sistema operativo. Ok probavelmente tenho algum registo que estou a mexer e que estou a fazer para bloquear o OS mas o problema e saber qual é mesmo esse registo (ou talves nao seja)
NOTA: Estou a utilizar o REal time clock do sistema.
Pois bem aqui apresento-vos o meu algoritmo.
Algoritmo Principal
1º Colocar o endereço da rotina int4a no vector interrupt 4aH
2º Colocar o endereço da rotina int1c no vector interrupt 1CH
3º Perguntar a Hora do Alarme
4º Configurar o Real Time Clock
5º Tornar este programa Residente
Algoritmo para a Rotina do Atendimento ao Interrupt 1Ch
1º Ler Hora
2º Converter a Hora de BCD para ASCII
3º Escrever a Hora
4º Ler Minutos
5º Converter os Minutos de BCD para ASCII
6º Escrever os Minutos
7º Ler Segundos
8º Converter os Segundos de BCD para ASCII
9º Escrever os Segundos
10º Ler Dia
11º Converter os Dia de BCD para ASCII
12º Escrever Dia
13º Ler Mês
14º Converter Mês de BCD para ASCII
15º Escrever Mês
16º Ler Ano
17º Converter Ano de BCD para ASCII
18º Escrever Ano
Algoritmo para a Rotina do Atendimento ao Interrupt 4aH
1º Dispara uma mensagem de Alerta.
O Codigo Fonte é o Seguinte:
.486
cseg segment use16
main proc far
assume cs:cseg
mov dx, offset int1c
mov ax, seg int1c
mov ds,ax
mov ah,25h
mov al,1ch
int 21h ;coloca o endereço da rotina int4a no vector de interrupt 4AH
mov dx, offset int4a
mov ax, seg int4a
mov ds,ax
mov ah,25h
mov al,4ah
int 21h ;Coloca o endereço da rotina int1ch no vector de interrup 1CH
;/////////////////////////////////////////////////////////////////////////////////
;DEFENIR O FORMATO A TRABALHAR (BCD)
mov al,0bh
out 70H,al
in al,71h
and al,11111011B
out 71H,al
;/////////////////////////////////////////////////////////////////////////////////
;--->Perguntar a Hora do Alarme
mov ah,1 ;;Fica a espera que o utilizador prime numa tecla
int 21H
sub al,'0' ;;Converte o codigo ASCII em binario
mov bl,al ;;Coloca o valor de al no bl
shl bl,4 ;;Converte o codigo binario para BCD
mov ah,1 ;;Fica a espera que prime outra tecla
int 21H
sub al,'0'
add bl,al ;; 12 d = 0001 0010 bcd
;Acrescentar a Hora ao Real Time Clock
mov al,05H
out 70H,al ;;Coloquei a hora do formato BCD no
mov al,bl ; ;Real Time Clock corresondente as
out 71H,al ;; horas do Alarme = 05H
;Perguntar os Minutos do Alarme
mov ah,1 ;;Fica a espera que o utilizador prime numa tecla
int 21H
sub al,'0' ;;Converte o codigo ASCII em binario
mov bl,al ;;Coloca o valor de al no bl
shl bl,4 ;:Converte o codigo binario para BCD
mov ah,1 ;;Fica a espera que prime outra tecla
int 21H
sub al,'0'
add bl,al ;; 12 d = 0001 0010 bcd
;Acrescentar os minutos ao Real Time Clock
mov al,03H
out 70H,al ;;Coloquei os minutos do formato BCD no
mov al,bl ;; Real Time Clock corresondente as
out 71H,al ;; horas do Alarme = 05H
;Defenir os Segundos do Alarme
mov bl,00000000
;Neste ultimo caso, o codigo BCD de 0 e igual ao binario
;Acrescentar os segundos ao Real Time Clock
mov al,01H
out 70H,al ;;Coloquei os segundos do formato BCD no
mov al,bl ;; Real Time Clock corresondente as
out 71H,al ;; horas do Alarme = 01H
;--->Configurar o Real Time Clock
;Colocar o Bit 5 e 6 do Status B a 1
mov al,0bH
out 70H,al ;; Activamos o Interrupt do Alarme
in al,71H ;; Activamos o Interrupts Periodicos
mov al,01100010B
out 71H,al
;IR ao Interrupt Mask Register e garantir k nao esta MASCARADO IRQ8 =A1H
in al,0a1h
and al,11111110B
out 0a1h,al
mov dx,zseg
mov ax,es
sub dx,ax ;determina o numero de paragrafos para deixar em memoria
mov ah,31h
int 21h ;termina o programa deixando o residente em memoria
main endp
;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int1c proc far ; rotina de atendimento ao interrupt
push ax
push bx
push cx
push di
push es ;faz o push de todos os registos que utiliza
;--->CRiar uma Subrotina Converte
converte proc far
mov bl, al
shr al, 4
add al,'0'
mov es:[di], ax
add di, 2
mov al, bl
and al, 00001111b
add al, '0'
mov es:[di], ax
add di, 2
ret
converte endp
;--->LER HORA
mov al, 04h ;coloca o valor das horas no registo al
in al, 71h ;le o que esta em 71h e coloca-lo no registo al
;--->Converte a hora de BCD para ASCII
Call converte
;--->Escreve Hora
out 70h, al ;escreve o que esta no registo al e coloca-lo no ;endereço indicado por 70h
;--->LER Minutos
mov al, 02h ;coloca o valor dos minutos no registo al
in al, 71h ;le o que esta em 71h e coloca-lo no registo al
;--->Converte a minutos de BCD para ASCII
Call converte
;--->Escreve Minutos
out 70h, al ;escreve o que esta no registo al e coloca-lo no ;endereço indicado por 70h
;--->LER segundos
mov al, 00h ;coloca o valor das segundos no registo al
in al, 71h ;le o que esta em 71h e coloca-lo no registo al
;--->Converte a segundos de BCD para ASCII
Call converte
;--->Escreve segundos
out 70h, al ;escreve o que esta no registo al e coloca-lo no ;endereço indicado por 70h
;--Posiçao da memoria video que queremos posicionar o cursor-----------------------------------------------------------------------------------
Mov di, 200 ; Coloca no offset o valor 200 (valor da posiçao de memoria video em que queremos que apareça o cursor)
;----------------------------------------------------------------------------------------------------------------------------------------------
;--->LER dia
mov al, 07h ;coloca o valor do Dia no registo al
in al, 71h ;le o que esta em 71h e coloca-lo no registo al
;--->Converte o dia de BCD para ASCII
Call converte
;--->Escreve dia
out 70h, al ;escreve o que esta no registo al e coloca-lo no ;endereço indicado por 70h
;--->LER Mes
mov al, 08h ;coloca o valor do mes no registo al
in al, 71h ;le o que esta em 71h e coloca-lo no registo al
;--->Converte a mes de BCD para ASCII
Call converte
;--->Escreve mes
out 70h, al ;escreve o que esta no registo al e coloca-lo no ;endereço indicado por 70h
;--->LER ANO
mov al, 09h ;coloca o valor do ano no registo al
in al, 71h ;le o que esta em 71h e coloca-lo no registo al
;--->Converte o ano de BCD para ASCII
Call converte
;--->Escreve ano
out 70h, al ;escreve o que esta no registo al e coloca-lo no ;endereço indicado por 70h
pop es
pop di
pop cx
pop bx
pop ax ; restaura todos os registos usados
iret ; termina a rotina de interrupt
int1c endp
;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
mesg db 'ALARME!! ALARME!! ALARME!! ALARME!!$'
int4a proc far ; rotina de atendimento ao interrupt
push ax
push bx
push cx
push di
push es ;faz o push de todos os registos que utiliza
;Definir um ponteiro de leitura
mov ax,0B800H
mov es,ax
mov di,0
;Definir um ponteiro de escrita
mov ax,seg mesg
mov ds,ax
mov si,offset mesg
;Ler o character do ponteiro de leitura
lb2: mov al, ds:[si]
;Comparar com '$'
Cmp al, '$'
;Se não for igual Escreve o carácter no ponteiro de escrita
JE Fim
mov es:[di],al
;Actualizar o ponteiro de escrita e de leitura
inc si
add di, 2
Jmp lb2
; Se for igual ao dólar terminar
Fim: pop es
pop di
pop cx
pop bx
pop ax ; restaura todos os registos usados
iret ; termina a rotina de interrupt
int4a endp
cseg ends
zseg segment use16
zseg ends ; segmento para calcular o tamanho do programa
end
OS programas que utilizo é o TASM + o LINK e depois para ver a execuçao linha a linha utilizo o Turbo DEbuguer.
SErá que alguem me pode ajudar com a parte do codigo?MAs porque que ele me Crasha? é essa a minha pergunta
Agradeço a vossa ajuda.
Última edição: