1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

Assembly Ajudem-me !!!!

Discussão em 'Programação' iniciada por Thorax, 3 de Junho de 2005. (Respostas: 9; Visualizações: 1526)

  1. Thorax

    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: 11 de Julho de 2007
  2. Sahaqiel

    Sahaqiel Power Member

    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.
     
  3. Thorax

    Thorax Power Member

    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
     
  4. caprr

    caprr Power Member

    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.
     
  5. Thorax

    Thorax Power Member

    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.
     
  6. Lancaster

    Lancaster To fold or to FOLD?

    Heyas all...

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

    Thorax Power Member

    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....
     
  8. DJ_PAPA

    DJ_PAPA Power Member

    Assembly rula :D

    Tenho exame para fazer daque a 2 semanitas.......

    WinDLX here!
     
  9. Thorax

    Thorax Power Member

    O meu é ja para a proxima semana... tenho apresentaçao na quarta e na quinta tauuuu frequencia... para me lixar os miolos...
    lol
     
  10. Lancaster

    Lancaster To fold or to FOLD?

    Heyas all..

    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 [[]]
     

Partilhar esta Página