Archiv verlassen und diese Seite im Standarddesign anzeigen : 8051 Stack in 80h - FFh ?
Hallo Assembler_fans,
bekanntlicherweise ist der untere ' internal data memory ' Bereich beim '51 Standard
direkt und indirekt ansprechbar. ( 00h - 7Fh ...128 Bytes)
Nun meine Wochenendfrage:
Kann man den Stack in den oberen ,nur indirekt ansprechbaren Ram_Bereich legen ?
( 80h - FFh ) ?
Habe ich nie ausprobiert....koennte heute nuetzlich sein !
Eine Frage um endlich vom Dauer OT wegzukommen :D
Hallo Ed,
ich habe zwar keine Ahnung mehr von Assembler aber versuche trotzdem e. Antwort:
meiner Meinung nach darf man das - Originalton Intel: "The stack may be located anywhere within the Internal Data RAM address space. The stack may be as large as 128 bytes on the 8051."
Jo,
stimme Rudo zu. Das darf man und das mache ich grundsätzlich immer.
Gruß,
guidob
Danke Rudo,
habe hier ein groesseres Programm und wegen Platzmangel im Ram war ich am ueberlegen......
Mein Stackpointer liegt z Zt.notwendigerweise bei 6Ah....und ich koennte so 22 bytes freimachen, das waere 'Luft' fuer das Programm,das viele Daten zwischen Server und '51 hin und her schaufelt....zwischenspeichern muss ich sie immer wieder.
Am 1° April dachte ich sogar daran ''' C ''' zu lernen weil das Program zu unuebersichtlich geworden ist...es gibt mir Tritte in den Hintern,die ICH gar nicht programmiert hatte.
Zum debuggen brauche ich viel Konzentration....die ich bei dem schoenen Wetter nicht auf die Beine bringe:mad:...leider...:confused:... oder doch ?
Ich versuche noch einen Ansturm auf den AssemblerBerg :D
Eine Hochsprache bringt natuerlich viel mehr Uebersichtlichkeit und die Schnittstellen zwischen den Modulen/Funktionen sind fest geregelt - d.h. man muss sich nicht darum kuemmern welche Funktion welches Register fuer welche Aufgabe beansprucht.
Fuers komfortable Debugging ist aber eher ein richtiger Hardware-Emulator notwendig - letzterer kann sogar bis zurueck auf den Sourcelevel verweisen. Dann kann man Breakpoints setzen und sich Registerinhalte ansehen. Fuer Systeme ohne Emulator kann man auch eine I2C-LCD-Anzeige oder Rx/Tx fuer die Testphase anschliessen, um sich Variablenwerte anzusehen etc.
Genau so ist es Rudo,
habe mir jetzt saemtliche Register (128) in eine Tabelle eingetragen und kann nun pruefen wo da theoretisch etwas schief gehen koennte. Eigentlich hatte ich alle Module / Unterprogramme mit dummy werten getestet....wahrscheinlich sind es die MSB und die LSB bei den Rechnungen mit 32 bit die manchmal vertauscht werden. dazu kommen noch Werte die ASCII sind und darunter habe ich dann noch HEX pur.....alles Punkte wo etwas schief gehen kann. Es genuegt ja ein '#' oder 'h' mehr oder weniger und alles ist hops....obwohl das ganze eigentlich ganz tuechtig loopt...leider aber falsche Ergebnisse bringt.
Geduld - we shall overcome :cool:
Der Assembler hat keinen Fehler gemeldet...aber der Simulator meldet:
Stack-Pointer ueber I_DATA-Top !!! :confused:
hey, vielleicht tuste zuviel pushen bzw. zu wenig poppen:rolleyes:
Ein Compiler zaehlt immer die "Dos" und "Ends" ab und meldet Fehler wenn ein Ungleichgewicht herrscht.
ich bin kein pusher...
eine 32bit Rechenroutine pusht vorsorglich - und unnoetigerweise - ''' 0 - 0Fh '''
das muss nicht sein ! da bin ich deiner Meinung. ;)
aber das Spiel Push gegen Pop geht 0 : 0 aus :D
Schoenen SA Abend ! ist das Wetter bei euch endlich etwas besser geworden ?
Ed, das Wetter hier ist grauenvoll! andererseits sollte es im April auch nicht besonders warm sein weil sonst der Sommer oft sehr nass wird.
32bit Rechenroutinen mit dem 2051er? So etwas habe ich stets nur mit dem 80C517A gemacht, der hat e. 32bit Coproz drin - dort brauchste nur die Register zu laden und nach 4µs holste das Ergebnis ab - koennte sogar noch meine Oma programmieren:D
Ich hoere immer gerne wenn gut ueber die OMAs gesprochen wird :D die haben es sicher auch verdient. Und sie haben immer gute Sprueche und Weisheiten bereit.
Die Siemens 300 und 500 Brocken habe ich nie angeschaut weil ich Siemens ein wenig hasse. Mir passt eher die amerikanische Art einer Loesung....SIEM... macht alles unnoetig kompliziert ! Ob 4 us oder 20 ms macht in meinem Fall keinen Unterschied.
Im Nebenzimmer laeuft ein irrer Film aus den 50-60iger Jahren...zum kaputtlachen.
Genug der Technik ...und hoffentlich stimmen die Prognosen fuer einen strahlenden Sommer...
dieses Jahr gehe ich wieder nach Sizilien (socken:eek:waschen) und das Leben geniessen.... am Meer
Uebrigens,solltest du mal nach Sizilien gehen.... In Taormina - Giardini Naxos steht eine Ferienwohnung fuer dich/euch bereit...:)
Hi,
es ist sogar sinnvoll den Stackpointer in die "scratch pad area" (oberster RAM Bereich) zu legen! Per default liegt der in einem Bereich, der beim bankswitching der "Schnell"registerbänke (RB0..RB7) benutzt wird. Diese können manchmal sehr praktisch sein, gerade bei Multitasking oder rekursiven Aufrufen (bis zu 8 ebenen) oder wenn eine Routine von der ISR (Interupt Service routine) mit aufgerufen wird und die Variablen umgeschaltet werden müssen. Darüber kommt der bitadressierbare Bereich, der ebenfalls zu schade für den Stack ist.
Rennt der Stackpointer über FF hinaus, so "schlägt der rund" und kommt von unten (00h) und überschreibt einem alle Variablen die im Wege liegen! Also immer brav ausrechnen, wie groß der Stack maximal werden kann und genug Speicher bereithalten. Das Rundschlagen kann man leicht erkennen, wenn man den Stackpointer in einer ISR abfragt und guckt, ob der plötzich im unteren RAM-Bereich liegt und das Programm mit einem Fehlercode (Blinkcode auf LED) anhält. Damit erkennt man was schief gegangen ist.
Gruß
Elmar
- koennte sogar noch meine Oma programmieren:D
Das ist ja ne clevere Oma! Schönen Gruß und Hochachtung !
Hallo Ed: Dein Stack geht bis 6Ah? Das ist ja jede Menge! Kannst du da nen Überlauf ausschließen (eigentlich schon, denn du "schrubst ja 0:0 beim pushen und pop(p)en). Wie schnell geht denn dein Datentransfer? Zusätzlichen Ram per I²C?
Hallo Elmar ,hallo Holger,
also mein Stapel beginnt bei 6Ah und reicht bis an das Ende (7Fh) des unteren I Data Rams. Das sind die 22Bytes die ich erwaehnt hatte. Ich lege meinen Stack immer ganz nach oben damit ich die Bitarea frei habe ....Bank switching mache ich nicht....und wie meine Frage schon angekuendete : Stack bis 0FFh das ist noch zu erkunden...da nur indirekte Adressierung moeglich.
Holger, das geht schon mit der vorhandenen RamGroesse....brauche und moechte keine zusaetzliche chips mehr verbauen.....es steckt irgendwo ein kleiner Fehler im prog....es ist mein Fehler....ich muss eben weiter debuggen oder zusaetzliche Routinen oder effizientere Routinen produzieren
Danke fuers reinkommen!
GutNacht........und ein HOCH an alle OMAs - und - an den BMW ....ein Pole in POLE Position !
Hallo Ed, noch munter? Bin grad vom Bauerntheater heimgekommen, hab noch Bauchschmerzen von den Lachkraempfen....
Ich lass bei meinen Progs den Stack, wo er von Haus aus ist und nutze RAM erst ab 30H. Bankswitching mache ich auch nicht, mir reichen in der Regel die 8 Register. Hat bislang immer so ausgereicht. Aber vielleicht probier ichs auch mal so, leg SP weiter nach hinten.
Jaja, das debuggen. Da brauch ich auch immer absolute Ruhe, da stört mich die Fliege an der Wand. Wenn dann meine Frau ins Zimmer platzt....Ein idealer Job für unterwegs!:D
Hallo Ed,
danke fuer das Angebot - ist aber eher unwahrscheinlich, dass wir uns mal soweit weg wagen.
Wo mein Compiler den stack hinpackt, weiss ich gar nicht - aber bestimmt werden damit keine direkt adressierbaren Bits blockiert, das wuerde ich ihm sehr uebel nehmen, denn davon kann ich gar nicht genug bekommen.
Das bankswitching sollteste aber mal in Betracht ziehen, mein Compiler verlangt, dass Interruptprogrammen verschiedener Prioritaet eine eigene Registerbank zugewiesen werden muss - wird schon seine Gruende haben ;)
Moin Ed,
hier haste den Wetterbericht von heute morgen (man kann leider nicht erkennen, dass es immer noch leicht schneit):
guten Tag,
Bauerntheater .... in welcher Sprache? /Dialekt ? Traenen Lachen..das ist besser als jegliche Medizin !
Was die Programmierung angeht....reicht sie mir immer gerade so aus...PI mal Schnauze Programmierung ohne viel Feinheiten. Ist einfach zu begruenden: Unkenntnis bestimmter Techniken...Bankswitching benoetige ich nicht weil ich meinen Zauber so gestalte dass es trotdem geht. Die Bitarea 20h...und folgende habe ich diesmal mehr genutzt als Flags und zum drehen von Daten usw.
Jeder eignet sich seinen eigenen mehr oder weniger effizienten Stil an wobei ich feststelle,dass ich immer groszuegiger mit dem Flash (Programmgroesse) umgehe.
Also keine Assemblerkunstwerke a' la Dannegger sondern ' Bauerntheater ' - Stil...zum lachen :D.
Am Ende kommt immer etwas brauchbares heraus....sonst haette ich schon damit aufgehoert...meine Kisten laufen in vielen Laendern der Welt ...nur zuletzt,seit Einsatz von China_Netzteilen...muss ich sie alle nach und nach austauschen: die BRENNEN durch....billige nicht spannungsfeste Kondensatoren :eek:
Rudo, so sah es zu Ostern auch aus .....brrr
Schoenes Photo ! Es sieht ja gut aus bei dir...hoffentlich baut da keiner mehr ! vor deiner Nase. Den Silbernen unter dem Dach erkenne ich wieder.
Hier sind praktisch alle Baeume gruen , die Rosen bereiten schon die ersten Blueten vor,Eidechsen sonnen sich eine MaxiHeuschrecke ist aufgewacht und es ist hoechste Zeit die Reben an einen Draht anzubinden, damit sie zum Balkon hinaufwachsen.
Heute F1 :)
Hallo Ed,
bauen kann man dort nicht, der silberne ist immer noch derselbe (ist erst bei ca. 50.000).
Beim Programmieren benutze ich auch immer wieder alte Vorlagen wie Schablonen und einige Dinge habe ich schon fast vergessen die selbstverstaendlich geworden sind.
Wenn du hier in der Gegend bist, klingel doch gerne mal an :)
Hallo Ed,
Stack bis 0FFh das ist noch zu erkunden...da nur indirekte Adressierung moeglich.
kapiere ich nicht, damit hast du doch nix zu tun (es sei denn du
manipulierst den Stackpointer, macht man doch nicht). Einfach
ein "mov SP,#0FFh" am Programmanfang, mehr ist es doch nicht. :confused:
guidob
Hi,
der C-compiler rechnet die maximalen Stackgrößen aus, die im UNGÜNSTIGSTEN Fall entstehen können. Dabei werden die vom Hauptprogramm (main) und die der Interrupts getrennt berechnet und addiert - zu recht. Aber es kann passieren, dass das Programm diese ausgerechneten "worst case" Werte Niemals erreicht, da die anzahl der Subroutinenebenen durch Abfragen begrenzt werden. So kann es für den Compiler aussehen, als wenn viel mehr benötigt wird oder gar unendliche Ebenen möglich sind. Das kann man nur durch Berechnung von Hand (Der Compiler versteht ja nicht, was das Programm genau macht) ausschließen oder "sauberer" programmieren um die theoretische Möglichkeit des Stacküberlaufes auszuschließen.
Worauf man aber UNBEDINGT achten muß ist, dass der selbe Programmteil (Subroutine) nicht durch "main" UND ISR (Interrupt) benutzt wird.
Dabei kann die Subroutine vom main aus gestartet laufen, arbeiten und variablen benutzen.
Dann wird die Routine angehalten und vom ISR neu gestartet. Bei wiederaufnahme nachdem die ISR fertig ist, steht die mitten drin vor veränderten Tatsachen - veränderten Variablen - und kann nicht mehr wie geplant arbeiten, da ja irgendwann mitten drin alles verändert wurde.
Das kann man sauber durch Bankswitching (ISR schaltet auf andere Bank und nach fertigstellung wieder zurück) mit dem selben Code bewerkstelligen oder man kopiert den Code 1:1 und vergibt andere Variablenadressen in der Kopie. Das Main arbeitet mit dem Original, die ISR mit der kopie. Das macht C automatisch, man merkt das nur durch den erhöhten ROM Speicherbedarf für die Kopie.
Gruß
Elmar
P.S.:
Ein Beispiel des main() vs ISR() problems in "Pseudocode":
main()
{
...
Länge=15;
Breite= 2;
Ergebnis = multiplikation(Länge, Breite);
Ausgabe(Ergebnis);
...
}
ISR()
{
...
x=2;
y=3;
z= multiplikation(x,y);
...
}
multiplikation(int a, int b)
{
...
c=a*b;
return(c);
}
Jetzt passiert folgendes. Wird die ISR nicht wärend der Abarbeitung von "multiplikation" ausgeführt, dann ist das Ergebnis "30", also korrekt.
Wird die ISR aufgerufen wärend "multiplikation" fast zuende ist (also genau vor "return"), dann kommt fälschlicherweise "6" als Ergebnis zurück.
Startet die ISR mitten in der Anweisung "c=a*b", dann kann alles mögliche dabei rumkommen, das Ergebnis ist REIN ZUFÄLLIG!
Hier hat der Programmierer drei Möglichkeiten:
1)
ISR im main() abschalten bevor "multiplikation" aufgerufen wird und hinterher wieder einschalten. Das weiss der Compiler nicht, der wird trotzdem eine Kopie anlegen, man verliert wertvolel Recourcen für gar nichts!
2)
Bankswitching im ISR. Auch hier merkt der Compiler das nicht und wird auch hier mit einer Kopie arbeiten
3)
Eigene Kopie anlegen, also "multiplikation_main(...)" und "multiplikation_ISR(...)" benutzen. Auch hier verliert man recourcen.
Bei einem guten Compiler kann man verbieten, dass im Fall 1) und 2) mit einer kopie gearbeitet wird.
Hi Guidob,
Einfach ein "mov SP,#0FFh" am Programmanfang, mehr ist es doch nicht. :confused:
In meinem Fall waere ich nicht gut damit bedient weil ja 0FFh das letzte Bytchen des indirekt adressierbaren Rams ist.Ich habe z Zt 22 Bytes fuer den Stack reserviert.
Ich werde heute noch testen ob das ueberhaupt funktioniert !
Oops ja,
Stack steigt ja, habe noch mal im getesteten Beispiel
nachgeschaut. :mad:
Also z.B. mov SP,#0E7h, kann man aber ruhig großzügig sein,
da der Bereich meist ja nur für Puffer o.ä. genutzt wird.
Gruß,
guidob
Hi,
alle Variablen die man braucht unten in das RAM packen und den Stack direkt darüber. So hat der Stack maximalen Platz für's gleiche Geld ;)
Gruß
Elmar
Hallo Gemeinde,
ich moechte die Herrschaften zur feierlichen Beerdigung der obigen Idee , den Stack in die Region 0x80 bis 0xFF zu verlagern , einladen.
Die Idee ist leider Stunden nach seiner Geburt blitzschnell abgelebt.
Also Stack zurueck...to where it belongs: in den Ram DATA Bereich..unterhalb 0x7F !
Bitte keine Blumen !
Hi,
benutzt du eigentlich RL51?
schau mal hier (http://www.esacademy.com/automation/docs/c51primer/c08.htm)
Benutzt du interrupts? wenn ja und du hast Zeit probier mal folgendes: mach nur (!) in der Hauptroutine ein kleines Fenster fuer IRQs auf: z.B.:
<main>
...
...
enable IRQ
nop
nop
nop
disable IRQ
...
...
sowas habe ich seinerzeit fuer IRQs vom GPIB-Controller µA7210 gemacht und das lief dann ohne Probleme.</main>
Hi,
peinlich, ich habe immer überlesen, dass die versucht wird den Stack in Bereiche zu legen, die gar nicht real existieren! Die "Scratch pad area" ist der höhste nutzbare Bereich und hört nach 128 Bytes auf! Könnte man den Stack höher legen, so würder der sinnlos in den Registern rumfummeln und alles mögliche mehr oder weniger zufällig verstellen! Oberhalb von 128 Bytes des RAMs ist kein RAM mehr, da existiert gar nichts. Nur einige Hardwareregister werden in den Adressbereich eingeblendet, scheinen sich also dort aufzuhalten, aber da ist in wirklichkeit nichts!
Das ist genau so als wenn man seine wichtigen Daten in /dev/nul speichert, weil da ist ja sooooo schön viel Platz drin! ;)
Gruß
Elmar
elmar,
formal haste natuerlich recht, nur die 52er haben dort ram, urigerweise dieselben Adressen wie die sfr.
Ich nehm aber an, dass Ed was 'vernuenftiges' benutzt wie z.B. AT89LP4052 oder so...
Hi,
jetzt ist die Sache fuer mich klar, danke Elmar fuer den Hinweis auf nicht existierende RamBereiche...Danke Rudo fuer den Hinweis auf 8052
im Post # 01 habe ich Standard 51 erwaehnt .
Bei dem ist oberhalb von den 128 Ram Bytes NICHTS
Beim 8052 existiert ein zweiter den SFRs ueberlagerter RamBereich.
ATMEL schrebt hierzu:
Note that stack operations are examples of indirect addressing,
so the upper 128 bytes of data RAM are available as stack space.
Jetzt ist alles geklaert.
Unmoegliches gibt es nicht :D
...kommt ne Woche zu spaet: 1.4. waer passender gewesen:D
Gut, dass ich das erst nach der Aufklärung lese.:D
Elmars Schocktherapie, dass ich bisher immer unmögliches getan habe,
hätte mich in Depressionen schicken können.
Gruß an alle,
guidob
Hi,
Elmars Schocktherapie, dass ich bisher immer unmögliches getan habe,
hätte mich in Depressionen schicken können.
Ich habe halt die Überschrift gelesen, da steht 8051 ;)
Gruß
Elmar
Powered by vBulletin® Version 4.1.12 Copyright ©2012 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.