Assembly Ajudem-me !!!!

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.
 
Última edição:
desculpa lá não te saber ajudar lá mto, mas gostava de te perguntar que livro é que leste para programar assim em assembly. Eu só tenho experiência em assembly de um processador simulado através de software, se não até te ajudava.
De qualquer forma, sei o seguinte que pode estar a afectar os registos.
Há registos que só aguentam 8 bits, outros 16 bits, e outros 32 .
Podes-te ter enganado e atribuir valores de mais de 8 bits aos de 8,etc.. Eu não te devo estar a dizer nada de novo, mas não custa verificar.
 
LOL na faculdade nao tenho livros .. por isso aprendi tudo com o prof .
Os registos sao todos de 16 bits AX = 16 bits dentro do AX temos o AH e o AL que sao de 8 bits cada um.
:P
 
viva

Se estas a simular podes identificar melhor onde esta o erro.
Tenta especificaar melhor o erro que da.

conselho->tenta organizar um pouco melhor o codigo e se possivel usares comentarios em c ou mais ilucidativos, pq isto de andar a ler assembly dos outros nao é simples.
 
PRoblema Resolvido

Pessoal ja sei qual é o problema do meu trabalho.. apos umas pequenas pesquisas no www.google.pt consegui desvendar o meu problema e espero poder ajudar o resto do pessoal que anda a aprender assembly.. entao é o seguinte..

Quando estamos a fazer uma Rotina de atendimento ao interrupt, dentro dessa rotina nao podemos fazer outra subrotina. no meu caso eu tinha o seguinte codigo dentro do RAI:

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

Esta Chamada tem de ser Feita Fora das RAI's porque o CPU le os Push todos e a proxima instruçao a ser executada era no exemplo que apresentei la em cima o MOV BL, AL e nao me li-a
o converte proc far ou seja quando chegava ao RET o cpu ia a Stack e retirava os valores que nao devia de tirar logo ai o meu OS crashava porque estava a destrui-lo.Contudo o converte proc far tem de estar fora dos RAI.

entretanto mais um pequena falha que tinha o meu programa era na parte de apresentar o relogio falta na ROtina de ATENDIMENTO AO INTERRUPT o codigo para colocar as horas minutos e segundos na memoria video ou seja logo mal começe tinha de colocar o seguinte codigo:

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



mov ax, 0b800h
mov es, ax ;posisao do cursor no monitor
mov di, 140
.
.
.
pop es
pop di
pop cx
pop bx
pop ax ; restaura todos os registos usados
iret ; termina a rotina de interrupt
int1c endp


Outro falha que cometi foi a ordem que coloquei os IN's e os OUT
O Real TIme Clock tem um Sistema de Agulhamento ou seja o 70H é o local onde quero que ele acessa as funcoes do relogio e o 71H é para saber o valor que tem dentro dessa funçao ou seja numa forma muito resumida queriamos aceder a parte da "Hora" e queriamos saber o valor que tem a "Hora" neste caso é meio dia entao o valor que la tem é 12 ou seja sao 12 horas. :)

LOGO na parte do codigo que programei do relogio o codigo correcto é :

mov al, 04h ;coloca o valor das horas no registo al
out 70h, al ;escreve o que esta no registo al e coloca-lo no endereço indicado por 70h
in al, 71h ;le o que esta em 71h e coloca-lo no registo al

;--->Converte a hora de BCD para ASCII e escreve no monitor

Call converte


COntudo ja esta tudo a Funcionar correctamente como que queria agora so me faltam acertar uns pequenos passos tipo editaçao e coisas minimas mas o objectivo do trabalho ja esta completo.

Espero que com isto ajude a muitos pequenos programadores de Assembly e a colegas meus de curso que andam F***Dos com estes trabalhos de caca.
Obrigado a todos e se precisarem de alguma ajuda podem contar cmg.
 
Heyas all...

Thorax disse:
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.

Deixa-me advinhar... Estudas no Instituto Politecnico da Guarda.... Será que acertei?

É só para deixar um linkzito...

Check This, foi o meu 1º post no fórum :D

Hasta all e espero ter ajudado...
 
Pois mais uma vez nao consegui fazer a maravilha da cadeira.. contudo tive de voltar a fazer de novo o trabalho. No ano passado optei pelo Alarme em Real time Clock .. este ano optei fazer Relogio + Data + alarme em Real time clock..

Desde ja agradeço-te porque foste umas das muitas pessoas que me ajudaram no ano passado. :003:

Com tudo como sei que existe pessoal que anda um pouco ****** com estes trabalhos principalmente no Instituto Politecnico da Guarda entao esta postado aqui para o pessoal saber pesquisar um pouco e ver as coisas como elas sao. Tento sempre ajudar os meus colegas de curso.. mas será que eles me ajudam a mim....
 
O meu é ja para a proxima semana... tenho apresentaçao na quarta e na quinta tauuuu frequencia... para me lixar os miolos...
lol
 
Heyas all..

Thorax disse:
Pois mais uma vez nao consegui fazer a maravilha da cadeira.. contudo tive de voltar a fazer de novo o trabalho. No ano passado optei pelo Alarme em Real time Clock .. este ano optei fazer Relogio + Data + alarme em Real time clock..

Desde ja agradeço-te porque foste umas das muitas pessoas que me ajudaram no ano passado. :003:

Com tudo como sei que existe pessoal que anda um pouco ****** com estes trabalhos principalmente no Instituto Politecnico da Guarda entao esta postado aqui para o pessoal saber pesquisar um pouco e ver as coisas como elas sao. Tento sempre ajudar os meus colegas de curso.. mas será que eles me ajudam a mim....

LOLOL, vi este post, e lembrei-me da outra thread...e pensei, vou buscar pode ser que o ajude alguma coisa, como é praticamente a mesma coisa...

Nem vi que eras o mesmo...lol, distrações..

Hasta all [[]]
 
Back
Topo