Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

STACK TASMA SORUNU

Başlatan borazan124, 18 Şubat 2011, 00:19:16

borazan124

kayan yazı programına çalışıken stack sorunu çıktı programı kısalttım. kolay incelemek için. proton ıde ile. 16f877 ile olmadı, 18f452 ile olmadı. Derlemede sorun yok proteusda sorun oluyor.  sizlerin yardımlarını bekliyorum
proteus,ta sadece 877 ve mclr ucuna + ile direnç bagladım
ETE hocamızın yaptıgı bas dosyalarını derleyemiyoruz. acaba hangi program derleyici ile derlenir                   
                       

  Device = 16F877

ADCON1=7
TRISA=%00000000
TRISB=%00000000
TRISC=%00000000
TRISD=%00000000
TRISE=%00000000
PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0
Dim MTNS As Byte
Dim DEGER As Byte                                                             
Dim MTN As Byte
Dim TKR As Byte
Dim AA As Byte
Dim EKBS As Byte
Dim YNB As Word
Dim SY As Word
Clear

Symbol CLK = PORTA.2                                                           
Symbol DAT = PORTA.1

YNB = 5000
DAT=0
CLK=0
'--------------------------------------------------------
Data "ACADE ABCDEE ABEDECC SSDSDSAAA AAA " 
'-------------------------------------------------------
CLK=0
DAT=1
CLK=1
CLK=0
DAT=0
CLK=1
CLK=0

BASLA: 


Read MTNS
DEGER = MTNS

Select DEGER
'-------------------------------------------------------(-)BOS 32
Case 32
PORTD=%00000000:CLK=1:DelayUS YNB:CLK=0:Inc SY
PORTD=%00000000:CLK=1:DelayUS YNB:CLK=0:Inc SY
PORTD=%00000000:CLK=1:DelayUS YNB:CLK=0:Inc SY
PORTD=%00000000:CLK=1:DelayUS YNB:CLK=0:Inc SY

'-------------------------------------------------------
'-------------------------------------------------------A 65
Case 65
PORTD=%11111110:CLK=1:DelayUS YNB:CLK=0:Inc SY
PORTD=%00001001:CLK=1:DelayUS YNB:CLK=0:Inc SY 
PORTD=%00001001:CLK=1:DelayUS YNB:CLK=0:Inc SY
PORTD=%11111110:CLK=1:DelayUS YNB:CLK=0:Inc SY
PORTD=%00000000:CLK=1:DelayUS YNB:CLK=0:Inc SY
'-------------------------------------------------------

End Select


GoTo BASLA
End

drmp

değerli arkadaşım stack taşma sorununun sebebi genellikle  call gosub return komutlarıyla alaklı hatadır ama senin programına baktığımda bir şey göremedim  programı kısalttım demişsin bir bak bakalım ne çıkacak   

Maxim

stack boyutu için bir komut var onu denedinizmi ?
declare stack_size = 40  mesela

https://www.picproje.org/index.php/topic,31564.0.html

Maxim

#3
Declare Stack_Size = 20 ' Create a small stack capable of holding 20 bytes

türkçesi: 20 byte tutabilmek için ufak bir stack yaratılıyor

ve helpte diyorki, 14bitlik piclerde 8 tane stack varmış
ama bunun 4 tanesini kullanabiliyormuşuz derleyicide, o yüzden 4 taneden fazla gosub komutu olmasın subrutinin içinde .
ama diyor 18F serilerinde 28 tane stack varmış ve 28 tane gosub kullanımı mümkünmüş

ete

Bir düzeltme yapayım yada ilave.
Stack taşmasını önlemek için bir birini takip eden 4 adet Gosub dan fazlasını kullanmayın.
Gosub YER1 şeklinde bir komut ile YER1 isimli alt programa gittiniz. Orada ikinci bir GOSUB ile başka bir yere atladınız.
İşte bir birini takip eden gosub adedinden bunu kast ediyorum. Yoksa program içinde tek gidiş dönüşülük 100 tane gosub olsa fark etmez.

Her gidilen gosub adresi stackta saklanırç Geri döndüğünüzde adres stack tan alınır ve stack in işi biter. Ama bir yere gittiniz adres stacke kayıt edildi, oradan ikinci bir yere gittiniz o adreste stacke kayıt edilir. Bu konumda en fazla 4 adres kaydı mümkün olduğundan fazlası olursa program geldiği adresleri kaybeder ve sonuçta ya kitlenir yada alakasız bir yerde kalır.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

Maxim

ayrıca başka bir takım şeylerde bu stack limitini etkiliyormuş
hepsini araştırmadım ama bir tane örnek vereyim
diyorki "declare ICD_req = on" deklarasyonunu kullanırken 14bitlik piclerde dikkatli olun
zira bu satır 2 stack götürüyormuş

yukarıda yazmıştım 14bitlik piclerde 4 tane stack var kullanılabilen.


14bitlik picler :

12C671, 12C672, ,12CE673,12CE674, 12F510
12F609, 12F615, 12F617, 12F629, 12F635, 12F675
12F683, 12HV609, 12HV615, 16C432, 16C433
16C554, 16C558, 16C61, 16C62, 16C620, 16C620A
16C621, 16C621A, 16C622, 16C622A, 16C62A
16C62B, 16C63, 16C63A, 16C64, 16C642, 16C64A
16C65, 16C65A, 16C65B, 16C66, 16C662, 16C67
16C71, 16C710, 16C711, 16C712, 16C715, 16C716
16C717, 16C72, 16C72A, 16C73, 16C73A, 16C73B
16C74, 16C745, 16C74A, 16C74B, 16C76, 16C765
16C77, 16C770, 16C771, 16C773, 16C774, 16C781
16C782, 16C84, 16C923, 16C924, 16CE623, 16CE624
16CE625, 16CR54, 16CR54A, 16CR57A, 16CR57B, 16CR57C
16CR58A, 16CR58B, 16CR62, 16CR63, 16CR64, 16CR65
16CR72, 16CR83, 16CR84, 16F505, 16F506, 16F526
16F610, 16F616, 16F627, 16F627A, 16F628, 16F628A
16F630, 16F631, 16F636, 16F639, 16F648A, 16F676
16F677, 16F684, 16F685, 16F687, 16F688, 16F689
16F690, 16F716, 16F72, 16F722, 16F723, 16F724
16F726, 16F727, 16F73, 16F737, 16F74, 16F747
16F76, 16F767, 16F77, 16F777, 16F785, 16F818
16F819, 16F83, 16F84, 16F84A, 16F87, 16F870
16F871, 16F872, 16F873, 16F873A, 16F874
16F874A, 16F876, 16F876A, 16F877, 16F877A
16F88, 16F882, 16F883, 16F884, 16F886, 16F887
16F913, 16F914, 16F916, 16F917, 16HV540
16HV610, 16HV616, 16HV785, 16LF722, 16LF723
16LF724, 16LF726, 16LF727, RF675F, RF675H
RF675K


FUNKY

Alıntı yapılan: ete - 18 Şubat 2011, 08:15:20
Bir düzeltme yapayım yada ilave.
Stack taşmasını önlemek için bir birini takip eden 4 adet Gosub dan fazlasını kullanmayın.
Gosub YER1 şeklinde bir komut ile YER1 isimli alt programa gittiniz. Orada ikinci bir GOSUB ile başka bir yere atladınız.
İşte bir birini takip eden gosub adedinden bunu kast ediyorum. Yoksa program içinde tek gidiş dönüşülük 100 tane gosub olsa fark etmez.

Her gidilen gosub adresi stackta saklanırç Geri döndüğünüzde adres stack tan alınır ve stack in işi biter. Ama bir yere gittiniz adres stacke kayıt edildi, oradan ikinci bir yere gittiniz o adreste stacke kayıt edilir. Bu konumda en fazla 4 adres kaydı mümkün olduğundan fazlası olursa program geldiği adresleri kaybeder ve sonuçta ya kitlenir yada alakasız bir yerde kalır.

Ete

ETE hocam  stack konusunu çok güzel anlatmışsınız   doğrusunu öğrendim ..teşekkür ederim..

HT

Benim gibi bu stack konusunda devamlı muzdarip olanlar varsa 8051 tabanlı işlemcilere geçmelerini tavsiye ederim.

drmp

müzdarip olan demişsiniz  bir şeyler sorun çıkarınca işlemci , derleyici falan vs değiştirmek  olmamalı ???

borazan124

Arkadaşlar teşekkür ederim. kısa sürede yardımcı olmaya çalıştınız. şimdilik sorun düzeldi gibi . 877 yerine 18f452 kullandım ,data komutu yerine write komutu kullandım.
Ama bu stack  lookup komutu ile yine sorun çıkardı , onuda komutun sonuna konan return komutunu kaldırınca şimdilik çözüldü.
bu stack meselesi her zaman canımızı sıkacak herhalde. çüzümleri paylaşırsak üstesinden geliriz galiba.

ete

Ortada bir sebep yok ise stack kesinlikle sorun çıkarmaz. Ben bu güne kadar bir kere bu sorunla karşılaştım ondada yukarıda açıkladığım hatalardan birisini yapmışım. Hatayı bulunca düzeldi. Kısaca siz hata yapmazsanız stack da size sorun çıkarmaz.
Sorun varsa programda sorun vardır. Genelde GOSUB ile gidilmiş yerlerden GOTO ile dönüldüğünde bu sorun ortaya çokça çıkmaktadır GOTO yerine Return koyduğunuz anda sorun ortadan  kalkacaktır.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

canbulut

#11
Alıntı yapılan: ete - 18 Şubat 2011, 08:15:20
Bir düzeltme yapayım yada ilave.
Stack taşmasını önlemek için bir birini takip eden 4 adet Gosub dan fazlasını kullanmayın.
Gosub YER1 şeklinde bir komut ile YER1 isimli alt programa gittiniz. Orada ikinci bir GOSUB ile başka bir yere atladınız.
İşte bir birini takip eden gosub adedinden bunu kast ediyorum. Yoksa program içinde tek gidiş dönüşülük 100 tane gosub olsa fark etmez.

Her gidilen gosub adresi stackta saklanırç Geri döndüğünüzde adres stack tan alınır ve stack in işi biter. Ama bir yere gittiniz adres stacke kayıt edildi, oradan ikinci bir yere gittiniz o adreste stacke kayıt edilir. Bu konumda en fazla 4 adres kaydı mümkün olduğundan fazlası olursa program geldiği adresleri kaybeder ve sonuçta ya kitlenir yada alakasız bir yerde kalır.

Ete
çok eski bir konuyu hortlatıyorum fakat gosub 'ı böyle anlamış olduk, peki goto kullanımları programa zarar verir mi? veriyorsa nasıl düzeltilir?if vb kodlarda böyle sıkıntılara yol açar mı?

ete

Goto komutu stack açısında zararlı değildir. Sebebini bilmiyorum ama Basic derleyicisini yazanlar da çok fazla Goto kullanmayın diye tavsiyede bulunurlar. Bu nedenle orantılı kullanmak en doğrusudur.

Gosub ile ilgili eski mesajlarıma bir ilave yapayım. Önceden 4 defadan fazla kullanmayın dediğim GOSUB komutu günümüzde yeni mikro denetleyicilerde stack hafızasının büyütülmüş olmasından dolayı daha da artırılabilir hale gelmiştir. Dolayısıyla işlemciye göre ayarlama yapmak en doğrusudur.

Stack mantığınıanlarsanız kimin zararlı kimin zarasız olduğuna kendinizde karar vereblirsiniz. Program bir yerlere gidip yine aynı yere geri dönecek ise mutlaka ayrıldığı adresi stack'a yazar ve dönerkende oradan alıp döner. Goto komutu programı zorunlu olarak bir adresten başka bir adrese yönlendirme yapar. Geri dönülmesi söz konusu değildir. Ancak başka bir goto ile aynı yere döndürürsünüz ki o zamanda stack gerekmez. Bildiğim stack en fazla Gosub , Kesme işlemlerinde kullanılmaktadır.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

z

Goto kullanmak günümüzde sorun olmamalı.

Eskiden if, while, do gibi döngülerin  içindeyken  goto ile çıkmak sorun olurmuş. Çünkü bu tip döngülere girerken bazı registerler vs saklanırken döngüden çıkarken registerlere eski değerleri yüklenirmiş. Ara bir yerden goto ile çıkınca bu reg,ster yükleme olayı yapılmadığından işlemci çuvallarmış.

Son derece basit bir yazılım (derleyici) hatası yüzünden goto sıkıntı yaşatırmış.

Artık derleyicilerde bu tip hatalar olmadığından goto kullanmanın fazla bir zararı yok. Gerçi pipe mekanizmasını çoğu zaman sıfırlasa da gotosuz program yazmak zaten imkansız. Sen yazmasan bile derleyici yazacaktır.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

canbulut

#14
kulandığım programda çok fazla gosub var fakat bir tanesi bile dahil return ile dönmeden işlem yapmıyorum. şu anda kısa bir şekilde kontrol ettikten sonra
if a=5 then atla komutu problem yaratıyor gibi geldi (olmadı başka yöntemler ile deneyeceğim).onun için araştırmaya başladım.