Objektorintiert vs Harvard

Hallo,

dieses Thema ist möglicherweise hier nicht ganz richtig trotzdem möchte ich aber dazu eure Meinung hören.

Ich schreibe an einem voll Delphi kompatiblen Compiler für Mikrocontroller ( AVR ). Das klappt alles soweit gut mit der Codeerzeugung. Ich habe allerdings jetzt ein Problem mit der Objektorientierung ( Klassen ). Ein Objekt oder Klasse wird normalerweise auf dem Stack sprich RAM erzeugt und dann auch der Code ausgeführt.

Nur Controller die auf einer Harvard Struktur basieren wie AVR oder 8051 können keinen Code im RAM ausführen. Beim 8051 oder ähnlich könnte man ja Schaltungstechnisch ROM und RAM umschalten aber bei AVR und Co. was tun ?

Ist die Harvard Struktur eine Sackgasse?

Ciao Günther

Reply to
Günther Kreischer
Loading thread data ...

Günther Kreischer schrieb:

Die Daten eines Objekts werden im RAM "erzeugt" aber doch nicht der Code. Der existiert für jede Klasse nur einmal. Jede Methode der Klasse bvesitzt einen versteckten Parameter der beim Aufruf einen Pointer auf zu bearbeitende Objekt (als die Daten des Objekts im RAM) enthält.

Ich seh da kein generelles Problem von Harvard vs. von Neumann.

--
Matthias Weißer
matthias@matwei.de
http://www.matwei.de
Reply to
Matthias Weißer

Oh nett. Meine Lieblingssprache und mein Lieblingscontroller. Wird das freie Software? (Es gibt übrigens einen leider nicht-freien voll Turbopascal kompatiblen Compiler für AVRs, wollte ich nur erwähnt haben ;-) )

Öhm? Also soweit mir bekannt werden da normalerweise nur die DATEN des Objekts auf dem Stack erzeugt. Den Code einer Klasse gibt es exakt einmal.

IMHO dürftest du keine Problem haben solange a) dein Code noch ins Flash passt b) du keinen Code nachladen willst ("DLLs" von Speicherkarte etc)

Reply to
Andreas Koch

Harvard kann gleichzeitig Zugriff auf Programm- und Datenspeicher durchführen und ist damit schneller. Solange man auf DIL40-Gehäuse u.ä. beschränkt war, war Von Neumann für LSI-Mikroprozessoren naheliegend. Mit den Einchip-Controllern kam Harvard in dem Bereich. Bei Bit-Slice u.ä. war Harvard wohl auch früher schon gängig.

Bytecode interpretieren. Bzw. schlicht die richtige CPU wählen. Von Neumann ist für Programmierung weiterhin weiterhin angenehmer.

MfG JRD

Reply to
Rafael Deliano

Ist eigentlich geplant.

Schon klar. Widerspricht das nicht der Kapselung ... ????

Will ich nicht. Erzeuge "pure" Assembler Code. Der Compiler ist rein für Mikrocontroller geplant.

Ciao

Reply to
Günther Kreischer

Salü Günter,

Objekte (Klassen) werden meines Wissens auf dem Heap abgelegt. (Die Funktion new() fordert Speicher auf dem Heep an (wie auch Fremem())).

Ich würde Dir eher empfehlen einen reinen Pascal-Compiler zu schreiben ohne die OOP-Erweiterungen.Dies reicht für microcontroller aus.Abgesehen davon brauchst Du viel mehr RAM imm uC und die ganze Sache wird langsamer und fehleranfälliger.

Viel Glück !! Ruedi

Reply to
Rudolf Wiesendanger

|> Ich schreibe an einem voll Delphi kompatiblen |> Compiler für Mikrocontroller ( AVR ). Das klappt alles |> soweit gut mit der Codeerzeugung. Ich habe allerdings jetzt |> ein Problem mit der Objektorientierung ( Klassen ). Ein Objekt |> oder Klasse wird normalerweise auf dem Stack sprich RAM |> erzeugt und dann auch der Code ausgeführt. |> |> Nur Controller die auf einer Harvard Struktur basieren wie AVR |> oder 8051 können keinen Code im RAM ausführen. Beim 8051 |> oder ähnlich könnte man ja Schaltungstechnisch ROM und RAM |> umschalten aber bei AVR und Co. was tun ? |> |> Ist die Harvard Struktur eine Sackgasse?

Eher die Objektorientierung... Der Code sollte schon aus dem ROM laufen können (ausser bei Sachen wie Reflection oder so), aber ich denke, dass deine Objekte samt virtueller Funktionstabellen etc. den Stack sprengen.

Im Endeffekt wird es bei dir wohl so laufen wie bei vielen anderen vordergründig ganz tollen OO-Sprachen/Tools für uCs: Es darf nur statische (d.h. zur Compilezeit auflösbare und anlegbare) Objekte geben.

--
         Georg Acher, acher@in.tum.de
         http://www.lrr.in.tum.de/~acher
         "Oh no, not again !" The bowl of petunias
Reply to
Georg Acher

Wunderbar.

Nein, wieso sollte es? Meines Wissens läuft das in Delphi ganz genau so.

Es hilft zum Verständnis vielleicht zu wissen, daß in Delphi alle Objekt-Methoden einen versteckten "self"-Parameter kriegen (also praktisch einen Pointer auf einen "Record" mit ihren Daten), wenn sie aufgerufen werden.

Reply to
Andreas Koch

"Georg Acher" schrieb im Newsbeitrag news:dp1hle$1im$ snipped-for-privacy@wsc10.lrz-muenchen.de...

können

Objekte

Man muss ja nicht Objektorientiert Programmieren. Aber es erleichtert vieles. Klassen sind (können ) einfach Klasse sein. Siehe Delphi VCL oder das weiss ich zu wenig drüber MFC.

vordergründig

Reply to
Günther Kreischer

Oder er müsste eine virtuelle Maschine implementieren, die im ROM residiert aber Befehle aus dem RAM liest und ausführt. Performancemässig natürlich eine Katastrophe.

Stefan

--
Stefan Heimers
http://www.heimers.ch/
Reply to
Stefan Heimers

Das ist so (wie der Vorposter sagt). Nein, denn wer/wie/wo auf den Code zugegriffen wird, regelt der Compiler/die Laufzeitumgebung. Also steht im RAM da wo die Klassenmethoden stehen ein pointer auf den code um RAM. Der code der member-funktions wird zum Glück nicht im Objekt mitgeschleift. Das wäre eine irre Platzverschwendung. Das (pointer auf code) ist aber nur bei dynamischen Sprachen nötig. Bei statischen Sprachen wie C++ weiß der Compiler schon welche Objekte daherkommen (viertelherzige Ausnahme ) und weiß somit wo der code der member-functions im ROM steht.

Gruß, Nick

--
Motor Modelle // Engine Models
http://www.motor-manufaktur.de
DIY-DRO -> YADRO
Reply to
Nick Müller

Stand auf ner langen Leitung. Warscheinlich ist die Weihnachts Ente dran schuld. ( Weiterverdau ).

Muss mir mal ein paar Gedanken über Änderungen im Codegenerator machen.

Ciao Günther --- und einen guten Rutsch

Reply to
Günther Kreischer

Nein.

Wie hier schon mehrfach erwähnt und somit nochmals bestätigt wird der Code für Funktionen einer Klasse nur _einmal_ pro Klasse erzeugt (*).

Die Funktionen erhalten dann bei ihrem Aufruf mit dem this-Pointer einen weiteren verdeckten Parameter, der auf den Datenbereich des Objekts zeigt. Damit ergibt sich für den Betrachter der Eindruck der Objektorientierung. Wunder vollbringt dies allerdings nicht, z.B. ist das Thema Garbage Collection so noch nicht gelöst.

Virtuelle Funktionen erhalten Zeiger im Datenbereich des Objekts, welche auf die entsprechenden Funktionen der abgeleiteten Klasse verweisen.

Zu Code im Datenbereich: Moderne Prozessoren wie der AMD64 verfügen explizit über ein No Execute Flag, um bösen Viren das Leben schwerzumachen, und spielen trotzdem mit C++, Delphi&Co. Selbstmodifizierender Code ist - Ausnahme sind spezielle Run-Time-Compiler (Java, Simulatoren) - im allgemeinen nicht erwünscht, die Ausnahmen machen bei größeren Prozessoren ein eigenes Codesegment auf.

Lediglich in diesen speziellen Fällen (P-Code-Runtime-Compiler) könntest Du mit der Eigenschaft Code-nur-im-ROM/Flash-erlaubt Probleme bekommen.

Gruß Oliver

P.s.: (*) Ollis neueste Erfindung erzeugt ihn manchmal mehrfach, aber nicht pro Objekt, und aus einem ganz anderen Grund ;-)

--
Oliver Bartels + Erding, Germany + obartels@bartels.de
http://www.bartels.de + Phone: +49-8122-9729-0 Fax: -10
Reply to
Oliver Bartels

Noch eine kleine Ergänzung: Bei C++ erzeugt der Compiler pro Klasse eine Virtual Table (mit Pointern auf die Klassen-Methoden). Die Virtual Tables sind statisch und können problemlos im ROM abgelegt werden. Jedes Objekt enthält nun zusätzlich zu den Member-Variablen einen Pointer auf die Virtual Table seiner Klasse.

Das sieht erstmal nach etwas Platzverschwendung im RAM aus, wenn man sich das genauer ansieht gibt's aber eine sehr offensichtliche Möglichkeit zur Optimierung:

Die Virtual Table muss nur Pointer auf "virtual" Methoden enthalten, also Methoden die von abgeleiteten Klassen überschreiben werden dürfen. Für den Fall, daß eine Klasse gar keine virtual Methoden enthält können die Virtual Table und die Virtual Table Pointer in den Objekten komplett entfallen.

Unterm Strich heißt das, daß die Objekte dann wirklich nur genau so viel RAM belegen wie die Member-Variablen benötigen (äquivaltent zu einer "struct" in C).

Das sollte man beim Design immer im Hinterkopf haben, vor allem wenn man eine größere Anzahl von kleinen Objekten hat ist der Unterschied im Speicherverbrauch durchaus signifikant.

Um auf's Originalposting zurückzukommen: Wie das bei Delphi genau aussieht weiß ich leider nicht, ich kenne mich da nur bei C++ aus. Aber vielleicht helfen die Anregungen ja trotzdem irgendwie weiter :-)

so long,

Hias

Reply to
Matthias Reichl

"Günther Kreischer" schrieb:

Nur mal so: sollte man da nicht eher GNU Pascal (gpc) um die OO-Dinge von Delphi erweitern statt das Fahrrad nochmal komplett zu erfinden?

In einem guten Compiler stecken wohl viele Mannjahre an Arbeit...

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

Das hängt davon ab ob man AVRs in Pascal programmieren oder einen (Delphi-)Compiler entwickeln möchte...

(Wie ist eigentlich die gcc/gpc-Code-Generierung für AVRs? Soweit ich weiss ist der GCC für 8-Bit-Targets doch von der gesamten Architektur her nur sehr bedingt geeignet?)

Reply to
Andreas Koch

Andreas Koch schrieb:

Der GCC hat meines Wissens nach ein grundsätzliches Problem mit den 2 getrennten Adressräumen von Harvard, jedenfalls ist er bei µCs mit nur einem Adressraum deutlich geschickter (auch bei 8-Bittern).

Grüße und Willkommen im neuen Jahr 2006 Erik

Reply to
Erik G.

IMHO ist die Codegenerierung prinzipiell recht gut, von Interrupthandlern mal abgesehen.

Der AVR-GCC kann halt mit _Daten_ im ROM nicht genauso umgehen wie im RAM. Dazu braucht man das Attribut PROGMEM und spezielle libc Funktionen (die mit dem 'P'). Das stoert den Programmierer, macht den entstehenden Code aber nicht schlechter (jedenfalls wenn der Programmierer wusste was er tat).

Von Hand wuerde man es stellenweise schon noch besser hinkriegen, aber das kann man dann an den wenigen Stellen ja auch tun wo es wirklich was bringt.

Micha

--
Mails containing HTML or binary windows code are rejected.
Reply to
Michael Baeuerle

Oliver Bartels schrieb:

Soweit klar. Das erklärt auch, warum es bei manchen kaputten Compilern möglich ist (nicht-statische) Memberfunktionen von nicht-existenten Objekten aufzurufen.

Hier formulierst Du ungenau:

Du meinst: Klassen mit virtuellen Funktionen ... aber ansonsten hast Du Recht.

Im Prinzip ist eine C++-Klasse ja nix anderes als ein C-struct mit eingebauten Funktionspointern.

Alles Grübeln hat bei mir nix gefruchtet. Verrätst Du es mir?

Markus

Reply to
Markus Becker

Nick Müller schrieb:

=== ROM?

Abgesehen von Deiner als viertelherzig bezeichneten Ausnahme, wie stellst Du Dir bei C++ die Realisierung virtueller Funktionen vor, die über einen Pointer auf die Basisklasse aufgerufen werden und automagisch die passende Funktion der abgeleiteten aufruft?

Ich bin mir jetzt nicht _ganz_ sicher, ob der Compiler unter allen Umständen schon zur Compilezeit alles richtig machen kann. Scheint aber im Laufe dieses meines Postings immer wahrscheinlicher geworden zu sein...

Markus

Reply to
Markus Becker

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.