Forum: Mikrocontroller und Digitale Elektronik SDCC-Assembler: Stack 8051 richtig organisieren


von Wilhelm F. (Gast)


Lesenswert?

Hallo zusammen,

vielleicht arbeitet ja hier jemand mit den SDCC-Tools für den 8051, und 
hat etwas Erfahrung.

Vielleicht hat jemand für mich eine Idee, weil ich aus den SDCC-Manuals 
zu Assembler und Linker, denen keine praktischen Beispiele bei liegen, 
nicht so richtig eindeutig schlau werde, wie ich es praktisch umsetze.

Ich kann vieles, aber bis auf ein paar wenige ungeklärte Prozent nicht 
alles.

Und zwar habe ich ein großes fehlerfreies asm-File gerade in viele 
kleine Module zerlegt, z.B. Timer, Interrupts, Keyboard, Display, 
Com-Schnittstelle, Arithmetik, Debug, und einiges andere. Nach 
Funktionsgruppen, alles kleine asm-Files. Sie alle haben ihre 
Segment-Definitionen für den Linker.

Das eine große Gesamtfile main.asm wuchs mir mit 1500 Zeilen gerade an 
Übersichtlichkeit über den Kopf, obwohl es noch keine 2kB Maschinencode 
assembliert. Es wuchs einfach in den letzten Tagen, waren anfangs nur 
ein paar Tests.

Die Files enthalten alle Segment-Definitionen für den Linker, z.B. Code, 
Data, Bits.

Die Assemblierung und Linkung klappt vorzüglich, nur der Stack macht 
Mist, weil ich den nicht anständig zuoberst platziert bekomme.

Der Stack muß beim 8051 zuoberst kommen, der Stackpointer wird mit der 
letzten oberen benutzten Speicheradresse initialisiert, weil er auf das 
Folgebyte zeigt, und wächst nach oben.

Die unteren Adressen zu platzieren, geht einwandfrei, die kann ich im 
Linker-Skript direkt angeben: Z.B. Bits ab 0x00, Idata ab 0x30 (direkt 
über dem Flag-Bereich).

Im Augenblick bekomme ich das nur so gelöst, daß ich einen Extra-File 
stack.asm machte, mit einem IDATA-Segment. Darin steht ein Stack-Symbol, 
und es wird ihm wenigstens der höchste Wert zugewiesen. Das funktioniert 
zwar, aber ich halte es für ein Provisorium, mehr Stümperei.

Denn, ich will die Assemblierung und Linkung im Command-File (Batch) mit 
einer FOR-Schleife automatisieren, die immer alle Files in einem 
Verzeichnis assembiert, und da ist nicht gewährleistet, daß das 
Stack-File als letztes dran kommt.

Es muß doch eine andere Möglichkeit geben!

Wenn ich das stack.asm nicht verwende, muß ich im Linker-Skript ein 
Stacksymbol mit festem Wert vorgeben. Z.B. Stack-Adresse an 0xA0. Das 
ist aber die schlechtere Lösung, unelegant. Es soll ja alles ganz 
automatisch gehen, und keine Bytes verschenkt werden.

Im Augenblick muß ich das stack.asm mit dem Stacksymbol als letztes 
linken, damit dieser IDATA-Bereich auf die vorherigen oben drauf gesetzt 
wird. Das funktioniert sogar augenblicklich nach ein paar Versuchen 
zuverlässig, aber weiß nicht, ob es in sich ändernden Konstellationen 
nicht auch zufällig ist.

von Bernd N (Gast)


Lesenswert?

Spezielle Fragen über den SDCC kannst du hier stellen.

http://sourceforge.net/projects/sdcc/forums/

>> Und zwar habe ich ein großes fehlerfreies asm-File gerade in viele
>> kleine Module zerlegt, z.B. Timer, Interrupts, Keyboard, Display,
>> Com-Schnittstelle, Arithmetik, Debug, und einiges andere. Nach
>> Funktionsgruppen, alles kleine asm-Files.

Warum löst du das nicht per "Include" und verwendest einen einfachen 
Macro Assembler und fertig ?

Ansonsten mach mal einen Versuch per inline ASM und mach ein C Projekt 
daraus und überlass dem Compiler / Linker den Job.

von Wilhelm F. (Gast)


Lesenswert?

Bernd N schrieb:

> Warum löst du das nicht per "Include" und verwendest einen einfachen
> Macro Assembler und fertig ?

Der SDAS8051 ist definitiv kein Makroassembler. Das hat auch nichts mit 
der Sache zu tun.

> Ansonsten mach mal einen Versuch per inline ASM und mach ein C Projekt
> daraus und überlass dem Compiler / Linker den Job.

Und Inline ASM im Assembler hat man auch nicht. Hat auch nichts mit der 
Sache zu tun.

Also: Mein Board hat nur 4kB ROM und 2kB RAM (glücklicherweise in 
Von-Neumann-Schaltung für Code-Download und Test), wobei ich das RAM im 
Augenblick im Monitorbetrieb zum Software-Test nutze, den Code da hinein 
lade. Deswegen, und nach Abwägungen, entschied ich mich bewußt gegen C. 
Ich hab lange überlegt und abgewogen, C geht definitiv nicht. Sorry, 
aber ich kann nicht 25% dieses minimalistischen Speichers noch für 
C-Overhead gebrauchen. Ich möchte da einiges (vieles) hinein bekommen, 
was unter C nicht geht. Mit meinen 64kB-Boards mache ich natürlich C, 
keine Frage.

von Bernd N (Gast)


Lesenswert?

Also ein reines ASM Projekt.

http://plit.de/asem-51/

Wie bereits erklärt, siehe oben.

von Wilhelm F. (Gast)


Lesenswert?

Bernd N schrieb:

> Wie bereits erklärt, siehe oben.

Erklärt ist hier bezüglich meiner Ausgangsfrage rein nichts.

Die Assembler Nr. 3 bis unendlich möchte ich jetzt nicht alle durch 
probieren, ich habe schon 2: Außer dem von SDCC noch den ersten ASM51, 
den INTEL mit der Entwicklung des 8051 initiierte, und der lange 
Standard war.

von Bernd N (Gast)


Lesenswert?

OK, du hast ein 100% Assembler Projekt, dann assemblier es.

SDCC ist ein C Compiler und du bastelst jetzt mit dem Compiler und 
Linker herum. Warum machst du kein C Projekt daraus und...
1
void main (void)
2
{
3
_asm;
4
dein Code
5
_endasm;

Bei einem reinen Assembler Projekt kannst du doch einfach einen Macro 
Assembler verwenden oder ?

>> Erklärt ist hier bezüglich meiner Ausgangsfrage rein nichts.

Du willst deinen Quellcode compilieren und genau das habe ich dir 
erklärt oder ?

von Peter D. (peda)


Lesenswert?

Mach dochmal ein Dummy C-Projekt und schau dort nach, wie der Compiler 
den Stack anlegt.
Z.B. beim Keil C51 wird der Stack im "startup.asm" angelegt.

Ansonsten kenn ich das auch nur so, daß man Assembler als ein File mit 
Includes assembliert, der Linker also garnichts machen muß.

Welchen 8051 verwendest Du denn, daß der RAM knapp so ist?
Die meisten heutigen 8051 z.B. von Atmel haben 256 Byte idata und 1kB 
xdata.

Ich verstehe auch nicht, warum es unbedingt immer der SDCC sein muß.
Nach meinem Eindruck hat der Wickenhäuser viel vom Keil abgeschaut 
bezüglich Optimierung und bis 8kB Demo ist für viele Projekte dicke 
ausreichend.


Peter

von Peter D. (peda)


Lesenswert?

Im Keil startup.asm steht folgendes:
1
;  To link the modified STARTUP.OBJ file to your application use the following
2
;  L51 invocation:
3
;
4
;     L51 <your object file list>, STARTUP.OBJ <controls>

Im Klartext, es muß als letztes in der Liste stehen.


Peter

von Wilhelm F. (Gast)


Lesenswert?

Bernd N schrieb:

> OK, du hast ein 100% Assembler Projekt, dann assemblier es.
>
> SDCC ist ein C Compiler und du bastelst jetzt mit dem Compiler und
> Linker herum. Warum machst du kein C Projekt daraus und...
>
>
1
> void main (void)
2
> {
3
> _asm;
4
> dein Code
5
> _endasm;
6
>
>

Danke für den Tipp, für Inline in einem SDCC-C-Projekt ist es zu viel 
Code, der auch noch auf viele Files verteilt ist.

> Bei einem reinen Assembler Projekt kannst du doch einfach einen Macro
> Assembler verwenden oder ?

Wie gesagt, ich habe noch den alten Makro-Assembler ASM51, und der ist 
sehr leistungsfähig. Von 1991. Ashling Microsystems. Es würde mich 
wundern, wenn die nicht auch den originalen Intel-8051-Assembler 
kreierten. Meiner von Ashling ist laut Buchbeschreibung von Siemens voll 
zum Intel-ASM51 kompatibel, hat noch zwei weniger bedeutsame 
Zusatzfeatures. Mehr nicht. Ich mußte dafür allerdings DOSbox 
installieren, weil auch nur der Simulator mit den Output-Files des ASM51 
läuft, mitnichten mit den Outputs von SDCC.

DOSbox lohnt sich, nur nebenbei mal bemerkt.

Die Assembler ASM51 und SDAS8051 unterscheiden sich gewaltig in der 
Quellcode-Syntaktik. Das einzige, was gleich ist, ist nur der reine 
mnemonische Code. Wenn auch sie das selbe Hex-File machen.

>>> Erklärt ist hier bezüglich meiner Ausgangsfrage rein nichts.
>
> Du willst deinen Quellcode compilieren und genau das habe ich dir
> erklärt oder ?

Du hast was erklärt, sicherlich. Und mich auch dazu bewegt, 
nachzudenken.

Ich wollte einen einfachen Hinweis für die Stack-Zuweisung in einem 
reinen Assembler-Projekt.

Notfalls könnte ich das Projekt vielleicht als leeren C-Code 
organisieren, mit dem SDCC-C-Compiler. Ich hatte dort in C auch reine 
ASM-Files drin eingebunden, wo es zeitkritisch war, nicht Inline, 
sondern richtig als Funktionsaufruf in einem reinen asm-File. Z.B. die 
Nachladung des Timer 0 im Interrupt. Im Extremfall könnte es eben nur 
mit ASM-Files laufen. Aber das wollte ich ursprünglich nicht.

Also, Bernd, nicht daß da Resistenz meinerseits auf kommt, ich betrachte 
deine Anmerkungen konstruktiv, und was ich da umsetzen kann. Reines 
Assemblerprojekt wäre mir aber auf jeden Fall lieber.



Peter Dannegger schrieb:

> Im Klartext, es muß als letztes in der Liste stehen.

Also so, wie ich es in meinem stack.asm jetzt auch habe. Hat Keil nicht 
auch eine Abart an Assembler vom originalen Intel ASM51? Ich meine, 
schon mal damit gearbeitet zu haben.

von Bernd N (Gast)


Lesenswert?

>> Danke für den Tipp, für Inline in einem SDCC-C-Projekt ist es zu viel
>> Code, der auch noch auf viele Files verteilt ist.

Deswegen auch der Hinweis von Peter ein Dummy Projekt anzulegen. Du 
kannst ja deine gesamten ASM Sourcen in Funktionen Packen und hast somit 
dann auch die Aufteilung in die einzelnen Dateien.

>> Und zwar habe ich ein großes fehlerfreies asm-File gerade in viele
>> kleine Module zerlegt, z.B. Timer, Interrupts, Keyboard, Display,
>> Com-Schnittstelle, Arithmetik, Debug...

also z.B.
1
void main (void)
2
{
3
    timer ();
4
etc.
5
6
void timer (void)
7
{
8
    _asm;
9
    dein Code
10
    _endasm;
11
}

Mir ist nicht klar warum du den Makro ASM nicht verwendest. Der von WW 
Heinz ist wirklich einwandfrei und würde ja dein Problem lösen.

Nur nebenbei bemerkt, SDCC kennt die Option --stack-auto, mir ist nur 
nicht klar wieso du Dein Projekt so angehst, seis drum.

Keil hat logischerweise auch einen Assembler an Bord und als der gute 
Rheinard angefangen hat war es eben nur der Assembler, lange her. Das 
Ding kostete so gute 2000 DM seinerzeit aber der ASEM51 macht den 
gleichen Job und die Zeiten haben sich doch sehr geändert :-)

von Wilhelm F. (Gast)


Lesenswert?

Danke noch mal, Bernd, für die Info.

Ich möchte mein ASM-Projekt so realisieren, als wenn es C gar nicht 
gibt. Genügt das, ist das jetzt deutlich?

von gerhard (Gast)


Lesenswert?

Ja, deutlich. Warum willst Du dann ausgerechnet den
Small Devices C Compiler als Problemlöser?

Gerhard

von Wilhelm F. (Gast)


Lesenswert?

gerhard schrieb:

> Ja, deutlich. Warum willst Du dann ausgerechnet den
> Small Devices C Compiler als Problemlöser?
>
> Gerhard

Nicht Ich wollte den C-Compiler, der wurde mir etwas weiter oben 
aufgedrückt. Zumindest, versucht.

von Wilhelm F. (Gast)


Lesenswert?

Die SDCC-Tools, auch wenn sie weitgehend funktionieren, aber das ist 
noch eine Baustelle:

Die Doku in ASxxxx Cross Assembler Documentation beschreibt für den 8051 
noch den AS8051-Assembler, der aktuell sdas8051 heißt, während ASLINK 
heute sdld heißt. Ulkig.

Die Beschreibungen in ASxxxx Cross Assembler Documentation sind 
überholt, und die beiden Tools haben im DOS-Fenster immerhin noch ein 
Hilfe-Fenster.

Vergangenes Jahr funktionierten nach einem Tools-Update des SDCC meine 
alten Projekte gar nicht mehr. Die Nasen hatten einfach die beiden 
Programmnamen von Assembler und Linker umgenannt. Den Assembler von 
as8051.exe nach sdas8051.exe, und den Linker von aslink.exe nach 
sdld.exe. Spaßig.

Wenn man die Namen in einem Command-File stehen hat, und ein altes 
Projekt wieder compiliert, gibt es erst mal: Nichts. Ein dummes Gesicht.

von Helmut (Gast)


Lesenswert?

Hallo Wilhelm,
mit dem SDCC Compiler habe ich zwar schon sehr lang nicht mehr 
gearbeitet. Vielleicht kann ich aber trotzdem etwas beitragen.

Wenn ich mir das C - Startup für den 8051 ansehe 
(http://sdcc.svn.sourceforge.net/viewvc/sdcc/trunk/sdcc/device/lib/mcs51/crtstart.asm?revision=8144&view=markup)
wird dort der SP mit '__start__stack' geladen.

Ich könnte mir vorstellen dass __start__stack ein vom linker generiertes 
Symbol ist das dieser auf das erste Byte des internen RAM legt das nicht 
von irgendwelchen anderen Variablen belegt ist.

Das kannst Du nachprüfen indem du in dem vom linker erzeugten File 
nachsiehst ob der auch bei Dir das Symbol mit dem passenden Wert 
erstellt hat.

von Wilhelm F. (Gast)


Lesenswert?

Helmut schrieb:

> Das kannst Du nachprüfen indem du in dem vom linker erzeugten File
> nachsiehst ob der auch bei Dir das Symbol mit dem passenden Wert
> erstellt hat.

Danke für den auch noch späteren Beitrag.

Inzwischen hab ich das für mich gelöst.

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.