Forum: Mikrocontroller und Digitale Elektronik PIC Variable und Stack


von Siegfried S. (dieleena)


Lesenswert?

Hallo,
PIC 18F2620  C18 Compiler.

möchte die Variable "macro_addr" auf dem Stack speichern und später 
wieder zurück hohlen.
1
  _asm
2
  PUSH
3
4
..  hier "macro_addr" ablegen
5
6
  _endasm
7
8
9
10
  _asm
11
..  hier "macro_addr" wieder zurückhohlen
12
  POP
13
  _endasm

weiter bin ich nicht gekommen. Gibt es auch einen direkten c Syntax, 
ohne das ich über die asm Schine muß ?

Gruß Siegfried

von Sunny (Gast)


Lesenswert?

Das geht so nicht.Du kannst im Stack keine Variable plazieren.

von Kein Name (Gast)


Lesenswert?

Verstehe das Problem nicht.

Wenn du eine ganz normale lokale Variable deklarierst, wird sie auf dem 
Stack abgelegt.

Und der Pic18 Stack ist doch die Katastrophe überhaupt. Der kostenlose 
Compiler generiert massenhaft Assemblerbefehle mit dem INDF2. Bei der 
Vollversion kann man Indexed Addressing einschalten.

Kein Masochist tut sich so was in Assembler an.

von Sunny (Gast)


Lesenswert?

Kein Name schrieb:
> Und der Pic18 Stack ist doch die Katastrophe überhaupt

Wieso? Der ist doch ganz gut.

von Kein Name (Gast)


Lesenswert?

Na ja.....

die Trennung von Programm- und Daten-Stack ist genial. Besser als alle 
Anti-Trojaner-Strategien auf den PCs.

Nur dieser aus Pic16 und modernem Hochsprachen-Stack 
zusammengeschusterte Datenstack.

von Sunny (Gast)


Lesenswert?

Da gib's eine  AN818 fom Microchip.Dort wird es genau beschrieben wie 
man Den Stack manipulieren kann.Aber er ist nur dafür da um den 
Programmablauf zu ändern.Also irgendwohin zu springen kann man damit 
aber keine Variablen dort ablegen.

von Peter D. (peda)


Lesenswert?

Beschreib dochmal Dein Problem.
In C gibt es bestimmt auch ne saubere Lösung dafür, ohne irgendwelche 
Assembler-Schweinereien.


Peter

von Michael S. (rbs_phoenix)


Lesenswert?

Kein Name schrieb:
> Verstehe das Problem nicht.

Und ich nicht den Sinn.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Stack

Der Stack wird benutzt, um die aktuelle Position beim Sprung in eine 
Unterfunktion / ein Unterprogramm zu speichern, damit der PIC beim 
Return der Funktion/Unterprogramm weiß, wohin er zurückspringen muss. 
Dahinein Variablen zu speichern ist eine nicht sehr sinnvolle Idee, 
zumal im RAM deutlich deutlich mehr Platz ist und er halt dafür da ist.


Kein Name schrieb:
> Und der Pic18 Stack ist doch die Katastrophe überhaupt. Der kostenlose
> Compiler generiert massenhaft Assemblerbefehle mit dem INDF2.

Das INDF-Register ist für die indirekte Adressierung und hat nichts mit 
dem Stack zutun. Man kann das FSR und INDF Register wie einen Pointer in 
C sehen. FSR ist die Adresse im RAM und INDF ist dann der Inhalt von der 
Speicherzelle.


Kein Name schrieb:
> Kein Masochist tut sich so was in Assembler an.

Das geht beim PIC18 genauso wie beim PIC16 und diesen hab ich in der 
Ausbildung mit ASM Programmiert und das war das kleinste Problem von 
allem. Man definiert vorher, welche Namen welche Adresse haben (muss man 
aber nicht machen) und sagt dann, man möchte etwas nach "variablea" 
schreiben.

z.B.:
1
L1  equ    0x0C
2
; ...
3
; ...
4
        decfsz L1, f

Nix mit FSR oder INDF.


Entweder ihr verwendet hier den Begriff "Stack" für etwas, was nicht der 
Stack ist, oder du/ihr solltet euch bewusst machen, für was man den 
braucht. Ich mach das Benzin ja auch in den Tank und nicht in die 
Baterie. Meineswissens kommt man an den Stack garnicht dran. Man kann 
höchstens den Program-Counter manipulieren, aber das is ja nichts 
anderes als ein GOTO.

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

Kein Name schrieb:
> Und der Pic18 Stack ist doch die Katastrophe überhaupt. Der kostenlose
> Compiler generiert massenhaft Assemblerbefehle mit dem INDF2. Bei der
> Vollversion kann man Indexed Addressing einschalten.

Völliger Blödsinn. Das einzigste was der freie C18 nicht macht ist die 
prozedurale Abstraktion als Code-Optimierung, und das auch nur nach 
einiger Zeit. Alles andere ist wie bei der Vollversion. SDCC wäre dann 
so oder so Open-Source, da gibt es also garkeine komerzielle Version die 
irgendwie eingeschränkt sein könnte. Was andere Compiler machen weiss 
ich nicht.

Michael Skropski schrieb:
> Das INDF-Register ist für die indirekte Adressierung und hat nichts mit
> dem Stack zutun. Man kann das FSR und INDF Register wie einen Pointer in
> C sehen. FSR ist die Adresse im RAM und INDF ist dann der Inhalt von der
> Speicherzelle.
>
> [...]
>
> Das geht beim PIC18 genauso wie beim PIC16 und diesen hab ich in der
> Ausbildung mit ASM Programmiert und das war das kleinste Problem von
> allem.

Die Pic18 haben da ganz enorme Unterschiede und vor allem Vorteile 
gegenüber den Pic16, was den Software-Stack im RAM angeht, als auch den 
Zugriff auf den Programspeicher im Flash.

Für den Zugriff auf das RAM stehen drei komplette Sätze an Registern zur 
Verfügung beim Pic18. Mittels der FSRxH und FSRxL Register legt man die 
(Ursprungs-)Adresse fest auf die die indirekten Zugriffe erfolgen 
sollen. (das x steht dabei für 0, 1 oder 2 - eben drei komplette Sätze).

Dann hat man die verschiedenen Register um den Zugriff zu machen. Einmal 
das normale INDFx, wie man es auch vom Pic16 kennt. Dann aber auch noch 
POSTINCx, POSTDECx, PREINCx und PLUSWx. Wenn man also einen SW Stack 
hat, setzt man lediglich beim Programstart die FSRx passend, und greift 
dann über PREINCx und POSTDECx darauf zu. PREINC erhöht die Adresse 
zuerst um eins und zeigt dann auf den neuen Wert. POSTDEC zeigt zuerst 
auf den Wert und dekrementiert dann die Adresse. Mittels PLUSW wird der 
Inhalt des WREG auf die Adresse addiert und dann zugegriffen, etc.

Da diese Sätze drei mal vorhanden sind, hat man beim Pic18 eine recht 
gute C Unterstützung: Stack und Frame-Pointer getrennt, und noch einen 
Indirekt-Satz feei fü z.B. Zugriffe auf Arrays.

Dann gibt es auch noch die TBLPTR Register, mit denen man ganz bequem 
direkt auf den Programmspeicher zugreifen kann, um z.B. Tabellen im 
Flash zu benutzen. Zu diesen Registern gibt es dann passende ASM 
Befehele für den Zugriff, ebenfalls mit Auto-Increment/Decrement/etc.

Wenn der OP also in Assembler programmiert, und dabei einen 
Software-Stack für Daten haben will, dann sollte er zuerst ein FSRxH/L 
auf den von ihm gewünschten Stack-Bereich setzen. Anschliessend schiebt 
er die Daten in das PREINCx Register, was einem PUSH entsprechen würde, 
und liesst sie dann aus dem POSTDECx Register wieder aus, was dann das 
POP wäre. Solange dieser Bereich dann für nichts anders genutzt wird, 
und der Registersatz ebenfalls nirgendwo anderweitig verwendet wird, 
reichen alleine diese zwei Register für den Zugriff auf den Stack aus. 
Ansonsten müsste ggf. das FSRxH/L Paar gesichert und später 
wiederhergestellt werden, sollte es wirklich mal für irgendwas nötig 
sein alle drei Registersätze verwenden zu müssen (z.b. um zwei Arrays zu 
verrechnen und das Ergebnis in ein drittes zu sichern, ohne viel 
Adress-Umladerei).

Grüße,

Chris

Edit: Man kann PREINC und POSTDEC natürlich auch vertauscht verwenden, 
je nachdem in welche Richtung der Stack wachsen soll.

von Siegfried S. (dieleena)


Lesenswert?

Hallo,

Danke für alle Infos. Werde das mit dem Stack vergessen und dafür ein 
Array anlegen.

Im Array speichere ich die Position(Offset) einer Tabelle. Je nach 
Inhalt der Tabelle wird ein neuer Offset zurückgegeben und dann im Array 
gespeichert. Dazwischen sind Ablauf-Anweisungen vorhanden und eine 
End-Anweisung. Tauch diese End-Anweisung auf, wird der vorheriger Offset 
zurück gelesen und dort weiter gearbeitet.

Gruß Siegfried

von Meister E. (edson)


Lesenswert?

Michael Skropski schrieb:
> Das INDF-Register ist für die indirekte Adressierung und hat nichts mit
> dem Stack zutun.

Lies bitte im Compiler-Handbuch, bevor du dich so weit aus dem Fenster 
lehnst. Auf Datenblatt-Basis hast du recht, mehr aber auch nicht.

Michael Skropski schrieb:
> Entweder ihr verwendet hier den Begriff "Stack" für etwas, was nicht der
> Stack ist, oder du/ihr solltet euch bewusst machen, für was man den
> braucht. Ich mach das Benzin ja auch in den Tank und nicht in die
> Baterie. Meineswissens kommt man an den Stack garnicht dran. Man kann
> höchstens den Program-Counter manipulieren, aber das is ja nichts
> anderes als ein GOTO.

Mach dich mit dem C18 und seiner ABI bekannt, dann wirst du sehen, dass 
der Compiler einen Daten-Stack im RAM erzeugt, der mittels FSRx 
verwaltet wird. Der Call/Return-Stack eines PIC16/18 kann freilich keine 
beliebigen Daten enthalten, das ist ja wohl klar.

Gruß,
Edson

von Kein Name (Gast)


Lesenswert?

Immer mit der Ruhe.

Die Hardware-Entwickler betrachteten nur den Call-Stack als Stack. In 
Hochsprachen wird die Kombination aus Daten- und Return-Stack als Stack 
bezeichnet.

Sind einfach nur 2 unterschiedliche Definitionen. Gab Verwirrung, ist 
aber inzwischen geklärt.

von Meister E. (edson)


Lesenswert?

Kein Name schrieb:
> Sind einfach nur 2 unterschiedliche Definitionen. Gab Verwirrung, ist
> aber inzwischen geklärt.

Dann ist es ja gut. Da der TE den C18 Compiler benutzt, gibt es aber nur 
eine gültige Definition von "Stack", nämlich die der ANSI-C89 
Spezifikation (leider nicht frei verfügbar wie der C99 Standard).
Der C18-spezifische Teil ist "implementation defined behaviour", 
nachzulesen im Compilerhandbuch.

Gruß,
Edson

von Peter D. (peda)


Lesenswert?

Daß für CALL/RET und PUSH/POP unterschiedliche Stacks verwendet werden, 
ist eine Spezialität des PIC.
Alle anderen Architekturen haben einen gemeinsamen Stack für beides. 
Dadurch sind auch reentrante Funktionen und rekursive Aufrufe kein 
Problem.

Aber unter C ist das eh egal, da dort ein Hineinpfuschen in den Compiler 
Pfui-Bäh ist.

Wenn Du unbedingt einen LIFO brauchst, dann lege Dir einfach ein Array 
und einen Pointer darauf an. Ein Hineinschreiben erhöht den Pointer, ein 
Auslesen verringert den Pointer und fertig ist der LIFO.
Natürlich gehört ein Test auf Unter- bzw. Überlauf mit hinein.


Peter

von Siegfried S. (dieleena)


Lesenswert?

Hallo Peter,
habe ich gemacht, einschließlich Unter-Überlauf. Stack ist für mich auch 
in Zukunft erledigt.
Routine läuft wie gewünscht.
schönen abend
Siegfried

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.