Thread View: pl.comp.lang.asm
10 messages
10 total messages
Started by KRUKERSradek
Fri, 04 Aug 2006 22:47
problem z przerwaniem 1ch
Author: KRUKERSradek
Date: Fri, 04 Aug 2006 22:47
Date: Fri, 04 Aug 2006 22:47
92 lines
2402 bytes
2402 bytes
Napisałem program który co jakiś czas ma wyświetlać wiadomość.Niewiem co
jest zle bo wcale tego nie robi.
Prosze o odpowiedz (proszę w odpowiedzi wysłać poprawiony cały kod i
wyjaśnienie, jeśli można)
program pisany pod asemblera tasm.
.MODEL SMALL
.STACK 256
.DATA
OLD_ADRES DD 00000000
LICZNIK DW 0000
BYTE_TIMER DB 00
MESSAGE DB 'MESSAGE','$'
.CODE
START:
.386
MOV AX,@DATA
MOV DS,AX
CALL INSTALL_TIMER
MAIN:
CALL DELAY
JMP MAIN
TIMER:
CLI
INC LICZNIK
CMP LICZNIK,10
JE TIMER00
JMP TIMER_RETURN
TIMER00:
MOV BYTE_TIMER,01
MOV LICZNIK,0000
JMP TIMER_RETURN
TIMER_RETURN:
STI
IRET
DELAY PROC NEAR
DELAY_GO:
CMP BYTE_TIMER,01
JE DELAY_RETURN
JMP DELAY_GO
DELAY_RETURN:
MOV BYTE_TIMER,00
MOV AX,0900H
LEA DX,MESSAGE
INT 21H
RET
DELAY ENDP
INSTALL_TIMER PROC NEAR
MOV AX,351CH
INT 21H
MOV WORD PTR OLD_ADRES,BX
MOV WORD PTR OLD_ADRES+2,ES
MOV AX,251CH
LEA DX,TIMER
PUSH DS
PUSH CS
POP DS
INT 21H
POP DS
RET
INSTALL_TIMER ENDP
UNINSTALL_TIMER PROC NEAR
PUSH DS
MOV AX,251CH
LDS DX,OLD_ADRES
INT 21H
POP DS
RET
UNINSTALL_TIMER ENDP
END START
Re: problem z przerwaniem 1ch
Author: Remek
Date: Sat, 05 Aug 2006 05:27
Date: Sat, 05 Aug 2006 05:27
16 lines
1257 bytes
1257 bytes
> proszę w odpowiedzi wysłać poprawiony cały kod
Nie ma tak dobrze. Nikt za Ciebie raczej nie zechce
wykonywać całej pracy. Ja widzę póki co nieskończoną
pętlę. W tym fragmencie:
delay_go:
cmp byte_timer, 01
je delay_return
jmp delay_go
Jeśli w zmiennej byte_timer nie pojawi się za pierwszym
razem wartość 01, program nie wyskoczy z pętli.
--
Remek
Re: problem z przerwaniem 1ch
Author: Remek
Date: Sat, 05 Aug 2006 06:31
Date: Sat, 05 Aug 2006 06:31
30 lines
1408 bytes
1408 bytes
Wprowadź tę zmienioną nieco procedurkę i sprawdź czy
działa tak jak chciałeś:
delay_return:
mov byte_timer, 00
mov ax, 0900h
lea dx, message
int 21h
lea dx, CRLF
int 21h
lea dx, CRLF
int 21h
lea dx, CRLF
int 21h
mov eax, 01FFFFFFFh
powtorz:
dec eax
cmp eax, 0
jnz powtorz
ret
delay endp
Poza tym należało by dołożyć zestaw instrukcji zakończenia
programu.
--
Remek
Re: problem z przerwaniem 1ch
Author: Bogdan (bogdro)
Date: Sat, 05 Aug 2006 08:25
Date: Sat, 05 Aug 2006 08:25
54 lines
2656 bytes
2656 bytes
KRUKERSradek napisał(a): > Napisałem program który co jakiś czas ma wyświetlać wiadomość.Niewiem co > jest zle bo wcale tego nie robi. Wyjaśniam poniżej. > Prosze o odpowiedz (proszę w odpowiedzi wysłać poprawiony cały kod i > wyjaśnienie, jeśli można) Żeby można było od razu zrobić Kopiuj+Wklej? Nie ma tak łatwo :). Poza tym, pisząc samemu, człowiek się uczy. > program pisany pod asemblera tasm. [...] > MOV AX,@DATA > MOV DS,AX > CALL INSTALL_TIMER > > MAIN: > CALL DELAY > JMP MAIN > > > TIMER: > CLI > INC LICZNIK > CMP LICZNIK,10 > JE TIMER00 > JMP TIMER_RETURN > TIMER00: > MOV BYTE_TIMER,01 > MOV LICZNIK,0000 Cs:[licznik], cs:[byte_timer] (lub ustaw DS), reszta zdaje się być dobrze. Czemu i po co tak? Pamiętaj, że procedura TIMER *nie* jest uruchamiana jako część Twojego programu. Jest uruchamiana przez BIOS, z niewiadomymi DS, ES, SS. Znany jest tylko CS. Jedno co wiadomo to to, że DS na pewno już *nie* wskazuje na Twój segment danych. Wykonując: inc licznik cmp licznik, 10 oczywiście operujesz na zmiennej, której offset jest taki sam, jak offset zmiennej "licznik", ale DS już nie jest dobrze ustawiony, więc operujesz na bajtach w innym segmencie, zaś w procedurze DELAY sprawdzasz bajty o tym samym offsecie, ale w swoim segmencie (które są oczywiście nienaruszone). -- Pozdrawiam, Bogdan (Linux i FreeDOS) Kurs assemblera x86 (DOS i Linuks): http://rudy.mif.pg.gda.pl/~bogdro Grupy dyskusyjne o asm: pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32 Prawdziwy, bezpieczny komunikator: www.JabberPL.org
Re: problem z przerwaniem 1ch
Author: Bogdan (bogdro)
Date: Sat, 05 Aug 2006 08:27
Date: Sat, 05 Aug 2006 08:27
24 lines
1817 bytes
1817 bytes
Remek napisał(a): >> proszę w odpowiedzi wysłać poprawiony cały kod > > Nie ma tak dobrze. Nikt za Ciebie raczej nie zechce > wykonywać całej pracy. Ja widzę póki co nieskończoną > pętlę. W tym fragmencie: > > delay_go: > cmp byte_timer, 01 > je delay_return > jmp delay_go > > Jeśli w zmiennej byte_timer nie pojawi się za pierwszym > razem wartość 01, program nie wyskoczy z pętli. Gdyby napisał prawidłowo, to by wyskoczył. Co jakiś czas zmienna ta miała być zmieniana przez przerwanie zegara, które działa oczywiście niezależnie od programu - "prawie" jak osobny wątek :) -- Pozdrawiam, Bogdan (Linux i FreeDOS) Kurs assemblera x86 (DOS i Linuks): http://rudy.mif.pg.gda.pl/~bogdro Grupy dyskusyjne o asm: pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32 Prawdziwy, bezpieczny komunikator: www.JabberPL.org
Re: problem z przerwaniem 1ch
Author: Bernard
Date: Sat, 05 Aug 2006 09:07
Date: Sat, 05 Aug 2006 09:07
112 lines
2916 bytes
2916 bytes
KRUKERSradek wrote: > Napisałem program który co jakiś czas ma wyświetlać wiadomość.Niewiem co > jest zle bo wcale tego nie robi. Po pierwsze - nie musi to działać pod Windows. > Prosze o odpowiedz (proszę w odpowiedzi wysłać poprawiony cały kod i > wyjaśnienie, jeśli można) Oczywiście. Ile płacisz? > program pisany pod asemblera tasm. Asembler. Biernik, nie dopełniacz. > .MODEL SMALL > .STACK 256 > .DATA > > OLD_ADRES DD 00000000 > LICZNIK DW 0000 > BYTE_TIMER DB 00 > MESSAGE DB 'MESSAGE','$' > > .CODE > > START: > .386 > MOV AX,@DATA > MOV DS,AX > CALL INSTALL_TIMER > > MAIN: > CALL DELAY > JMP MAIN > > > TIMER: > CLI Zbędne. IF jest już równy 0. > INC LICZNIK Procesor wykonuje w tym momencie dostęp do nieznanej komórki pamięci, o adresie LICZNIK liczonym względem bieżącego DS, który jest dość losowy. > CMP LICZNIK,10 > JE TIMER00 > JMP TIMER_RETURN Te dwa skoki są równoważme jednemu JNE. To samo dalej. > TIMER00: > MOV BYTE_TIMER,01 > MOV LICZNIK,0000 > JMP TIMER_RETURN > TIMER_RETURN: > STI Zbędne. IRET i tak zamaże IF. > IRET > > > > > DELAY PROC NEAR > DELAY_GO: > CMP BYTE_TIMER,01 > JE DELAY_RETURN > JMP DELAY_GO > DELAY_RETURN: > MOV BYTE_TIMER,00 > MOV AX,0900H > LEA DX,MESSAGE > INT 21H > RET > DELAY ENDP > INSTALL_TIMER PROC NEAR > > MOV AX,351CH > INT 21H > MOV WORD PTR OLD_ADRES,BX > MOV WORD PTR OLD_ADRES+2,ES > > MOV AX,251CH > LEA DX,TIMER > PUSH DS > PUSH CS > POP DS > INT 21H > POP DS > RET > INSTALL_TIMER ENDP > > > UNINSTALL_TIMER PROC NEAR > > PUSH DS > MOV AX,251CH > LDS DX,OLD_ADRES > INT 21H > POP DS > RET > UNINSTALL_TIMER ENDP > > END START > > >
Re: problem z przerwaniem 1ch
Author: Remek
Date: Sat, 05 Aug 2006 09:16
Date: Sat, 05 Aug 2006 09:16
19 lines
1265 bytes
1265 bytes
> reszta zdaje się być dobrze
Chyba jest dobrze, bo działa (sprawdziłem). Dołożyłem to:
CRLF db 0DH,0AH,'$'
......
lea dx, CRLF
int 21h
lea dx, CRLF
int 21h
lea dx, CRLF
int 21h
aby messag nie był wyświetlany "ciurkiem" w jednym
łańcuchu. Przydałaby sie również procedura zakończenia
programu.
--
Remek
Re: problem z przerwaniem 1ch
Author: Remek
Date: Sat, 05 Aug 2006 09:21
Date: Sat, 05 Aug 2006 09:21
9 lines
1111 bytes
1111 bytes
> Wprowadź tę zmienioną nieco procedurkę i sprawdź czy działa tak jak chciałeś ... Powyższy post poszedł przez pomyłkę. Czy na tym serwerze można anulować wiadomość? -- Remek
Re: problem z przerwaniem 1ch
Author: Remek
Date: Sun, 06 Aug 2006 02:28
Date: Sun, 06 Aug 2006 02:28
16 lines
1421 bytes
1421 bytes
> Gdyby napisał prawidłowo, to by wyskoczył. Co jakiś > czas zmienna ta miała być zmieniana przez przerwanie > zegara, które działa oczywiście niezależnie od programu > - "prawie" jak osobny wątek Nawet nie warto się powtarzać, bo to oczywiste: Jak zwykle masz rację, a mnie wstyd, że tego sam nie zauważyłem. Nie śmiem Cię prosić o rozszerzone omówienie tych zagadnień na przykładzie którejś z funkcji przerwania DOS'u i BIOS'u na swojej stronie. Pozdrawiam -- Remek
Re: problem z przerwaniem 1ch
Author: Bogdan (bogdro)
Date: Sun, 06 Aug 2006 08:34
Date: Sun, 06 Aug 2006 08:34
30 lines
2464 bytes
2464 bytes
Remek napisał(a): >> Gdyby napisał prawidłowo, to by wyskoczył. Co jakiś >> czas zmienna ta miała być zmieniana przez przerwanie >> zegara, które działa oczywiście niezależnie od programu >> - "prawie" jak osobny wątek > > Nawet nie warto się powtarzać, bo to oczywiste: > > Jak zwykle masz rację, a mnie wstyd, że tego sam nie > zauważyłem. Nie śmiem Cię prosić o rozszerzone omówienie > tych zagadnień na przykładzie którejś z funkcji przerwania > DOS'u i BIOS'u na swojej stronie. Nie musisz :) Od tego jest mini-kurs pisania programów rezydentnych (TSR-ów). Co prawda, nie używam pamięci do przekazywania danych między programem a procedurą obsługi przerwania, ale są zmienne obecne na raz w części rezydentnej i w programie głównym. Nie przejmuj się tym, że nie wszystko widać. To przychodzi z doświadczeniem. Podobnie, jak dostawianie CS:[]. Jak człowiek jeszcze się z tym nie spotkał, to może tylko liczyć na debuger, a i to nie zawsze może pomóc. Ja trafiłem na taki "bajer" z nieustawianiem DS, pisząc TSR-a do wspomnianego kursu (a może jakiś inny?). Wtedy to się naszukałem bugów :) i dzięki temu teraz jestem wyczulony na takie coś. -- Pozdrawiam, Bogdan (Linux i FreeDOS) Kurs assemblera x86 (DOS i Linuks): http://rudy.mif.pg.gda.pl/~bogdro Grupy dyskusyjne o asm: pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32 Prawdziwy, bezpieczny komunikator: www.JabberPL.org
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads