Emulator przy M-IDE'51

To forum jest dla wszystkich pasjonatów wiecznie młodych mikrokontrolerów '51. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
mentos_007
-
Posty: 14
Rejestracja: 12 paź 2007, 12:04
Lokalizacja: Szczecin
Kontakt:

Emulator przy M-IDE'51

Post autor: mentos_007 » 04 sty 2008, 12:41

Uzywam programu M-IDE Studio for MCS-51, przy tym jest Emulator 8051.
W mojej procedurze musiałam użyć sjmp $ (petli nieskonczonej) zeby zakonczyc procedure. Czy da się jakos "zatrzymac" emulator automatycznie gdy natknie się na taką pętle? W tej chwili za każdymr azem muszę kliknąć najpier RUN a później STOP. jednak chciałabym by sam się wyłączał... da rade? :-)

Gdy konczę procedure zwykłym END pojawia się ostrzeenie o przepełnieniu stosu :-( dlatego wykorzystałam sjmp $

tasza
Użytkownik
Posty: 1391
Rejestracja: 21 lut 2005, 15:02

Post autor: tasza » 04 sty 2008, 13:50

Nie pogniewaj się....ale chyba niewłaściwie podchodzisz do tematu.

Procedur (zamkniętych fragmentów kodu zakończonych RET/RETI) nie należy
testować w taki sposób. Znacznie lepiej napisać te kilka linijek dodatkowego kodu,
który zapewni "naturalne" wywołanie (i zakończenie) procedury.
Wyniki pracy procedury możesz obejrzeć po jej zakończeniu lub "w locie",
za pomocą pracy krokowej. Popatrz na takie coś:

Kod: Zaznacz cały

	; ustaw stos na 20h
	mov SP, #20h
	;
	; wywolanie procedury
	lcall any_proc
	;
	; martwa petla
	ljmp $
	;
	;
any_proc:
	mov DPTR, #1234h
	movx A,@DPTR
	ret
	;
	end
Do wnętrza procedury wchodzisz poleceniem Step Into, jak Cię nie ciekawi
co jest wewnątrz to Step Over....
Wyniki pracy to stan rejestrów/pamięci/portów po wywołaniu.
Jeżeli chcesz zatrzymać wykonywanie kodu w dowolnym miejscu - to od tego
są pułapki (breakpoints). W emulatorze definiuje (zastawia) się je tak:
klikasz w dowolną instrukcję w okienku Disassembled Code,
pojawi się okno dialogowe "Edit breakpoints", w nim będzie już wstępnie ustawiona
wartość Location czyli punktu przerwania pracy, wciskasz Add - pułapka doda się do listy,
potem Done - i to wszystko.
Wywołanie Start - uruchomi kod, aż do momentu napotkania pierwszej pułapki,
potem emulator przerwie wykonywanie kodu, możesz na spokojnie oglądać
co się w środku dzieje....kolejne Start - wykona program do następnej zdefiniowanej
pułapki (o ile takowa będzie). W załączeniu - zrzutka ekranu z dwiema pułapkami
w nic-nie-robiącej procedurze any_proc

ps.
powyższe dotyczy tej wersji środowiska:
http://www.opcube.com/software/midepack02510.exe
Załączniki
mide_breakpoints.gif
(42.02 KiB) Pobrany 611 razy

mentos_007
-
Posty: 14
Rejestracja: 12 paź 2007, 12:04
Lokalizacja: Szczecin
Kontakt:

Post autor: mentos_007 » 04 sty 2008, 18:41

Dlaczego miałabym się pogniewać? jestem w tym zielona i dopiero się ucze :-) Dziękuję Ci bardzo za wskazówkę z tymi Breakpoints'ami - właśnie o coś takiego mi chodziło, żeby to ... zatrzymac :-) podglądam sobie wartości które mi się podczas procedury zmieniają w okienku "Internal RAM" i wszystko mi działa tak jak chciałam :-) Przynajmniej mikrokontroler się mnie słucha :)

Zrobiłam test tak że na górze zadeklarowałam sobie miejsca w pamięci na jakies tam moje zmienne (np cyfra1 equ 020h), niżej wrzuciłam wartości początkowe (zwykłym mov) a później jest LCALL procedura i ljmp $, a dopiero niżej procedura :-)

Dziekuje za odpowiedź!

tasza
Użytkownik
Posty: 1391
Rejestracja: 21 lut 2005, 15:02

Post autor: tasza » 07 sty 2008, 11:47

mentos_007 pisze:Zrobiłam test tak że na górze zadeklarowałam sobie miejsca w pamięci na jakies tam moje zmienne (np cyfra1 equ 020h), niżej wrzuciłam wartości początkowe (zwykłym mov) a później jest LCALL procedura i ljmp $, a dopiero niżej procedura
Czasem lepiej załączyć kawałek listingu (w tagach CODE), opis słowno-muzyczny
można niekiedy źle zinterpretować...
Co do stosu - uważaj na jedną rzecz - aby w trakcie odkładania na stos
kolejnych adresów (rozkazy typu CALL) lub odkładania danych (rozkaz PUSH)
nie uległy uszkodzeniu (zamazaniu) zmienne programu, które zdefiniowałaś.
Stos w '51 ma to do siebie, że jego wierzchołek (aktualna wartość rej. SP) przesuwa
się w kierunku rosnących adresów, więc zmienne robocze i inne takie należy deklarować
__poniżej__ dna stosu czyli pierwszej wartości wpisanej do rej. SP (inicjacja stosu).
Poniżej masz przykład, jak bezsensownie umiejscowione zmienne (zmienna1...3)
zostaną zamazane przez pracujący podczas wywołania procedury any_proc stos.

Kod: Zaznacz cały

	; STOS - demolka
	;
zmienna1 equ	22h
zmienna2 equ	23h
zmienna3 equ	24h
	;	
	; ustaw stos na 20h
	mov SP, #20h
	;
	; zainicjuj jakies zmienne
	mov	zmienna1, #0aah
	mov 	zmienna2, #55h
	mov	zmienna3, #99h	
	;
	; wywolanie procedury
	lcall any_proc
	;
	; martwa petla
	ljmp $
	;
any_proc:
	push acc
	mov DPTR, #1234h
	movx A,@DPTR
	pop acc
	ret
	;
	end
Zmienne mają adresy 22h,23h,24h, dno stosu - 20h, po zakończeniu
procedury any_proc - jest "pozamiatane" :(
Najlepiej wrzuć sobie w/w programik do symulatora i oglądnij na pracy krokowej
(rozkaz po rozkazie) jak uszkadzają się kolejne wartości zmiennych...taki pokaz dobrze robi.
A pisze Ci to dlatego, że tego typu błędy jest bardzo ciężko wyłapać,
one nie zawsze wychodzą podczas symulacji...

Natasza

PS.
Po resecie wartość dna stosu w '51 to adres 07h - więc jeżeli korzystasz
z pamięci IDATA (internal RAM) w większej ilości - stos __trzeba świadomie zainicjować__
bezpieczną dla zgromadzonych tam danych wartością. Inaczej - kolorowe kredki.

ODPOWIEDZ