Forum: Mikrocontroller und Digitale Elektronik Verständnisfrage zu Assembler bei PIC und ATMEL


von Jürgen K. (geduld)


Lesenswert?

Ich beschäftige mich seit Längeren bereits mit ATtiny85, ATMega328 und 
jetzt auch mit PIC. Angefangen habe ich mit den Lernbausätzen von 
Franzis. Interessante Anregungen habe ich als Anfänger unter anderen bei 
BKainka bzw. seinem Elektronik-Labor gefunden. Er hat wohl auch den 
Lernbausatz ATtiny85 für Franzis entwickelt.

Inzwischen sind mir die Vorteile/Unterschiede zwischen der 
Programmierung via Bootloader oder mittels Programmer klar.

Da ich bisher nur Hochsprachen wie Bascom oder C benutzt habe, war 
Assembler erst einmal zweitrangig. Allerdings läuft im Mikrocontroller 
natürlich in Maschinensprache übersetzter Code, egal ob aus Bascom oder 
C.

Wenn ich nun mit einem Programmer (STK500 bei ATMEL oder PICKit bei PIC) 
einen Controller komplett auslese, welcher mittels Bootloader über die 
Serielle Schnittstelle/USB programmiert wurde, finde ich natürlich im 
untersten Speicherbereich den Bootloader und z.B. bei PIC ab 0400hex das 
eigentliche Programm. Diesen Inhalt ab 0400hex könnte ich natürlich 
abspeichern und wieder in einen jungfreulichen Controller laden. 
(Configbits bzw. Fuses nicht vergessen)
Will ich jetzt allerdings den Bootloader weglassen, so könnte ich doch 
nur den eigentlichen Maschinencode des Anwendungsprogrammes speichern, 
der ab 0400hex zu finden ist. Das spart Speicherplatz und reicht für 
fertige Geräte ja völlig aus, welche nur einmal programmiert werden 
sollen.

Bei diesem Gedankengang kamen mir dann folgende Fragen:

1. Gibt es bei PIC/ATMEL im Assembler auch absolute 
Sprünge/Sprungadressen?

2. Kann ich den eigentlichen Programmcode ab 0400hex einfach an eine 
andere Adresse verschieben?

Falls Frage 1 mit "Ja" zu beantworten ist, dann sollte Frage 2 bzw. das 
Verschieben nicht möglich sein. Oder sorgt der Compiler bei diesen 
Controllern (ATtiny85, ATMega328, PIC18F23K22) dafür, dass es keine 
absoluten Sprünge gibt?

Sorry für die etwas akademische Frage, aber für mein Verständnis 
durchaus wichtig.

von Oliver S. (oliverso)


Lesenswert?

Die AVRs haben absolute Sprünge (jmp) bei den Modellen, bei denen der 
relative Sprungbefehl (rjmp) nicht für den gesamten Flash ausreicht.

guggst du Datenblatt.

Oliver

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

Wobei ich mich gerade frage, welchen Sinn die Fragestellung für Atmel 
ergibt: bei den genannten Typen (Klasse 'AVRe') befindet sich der 
Bootloader doch am Ende des Flash.

PS:
Auch dies verstehe ich nicht:
> Das spart Speicherplatz ...
Welchen Vorteil soll das haben?

: Bearbeitet durch User
von Jürgen K. (geduld)


Lesenswert?

Danke für den Hinweis. Das würde bedeuten, dass meine Gedanken nur bei 
den PICs zutreffen würden, da dort der Bootloader vorn (0 - 0400hex) 
liegt. Bei den Atmels würde sich ja nichts an den Adressen verändern, 
wenn ich nur den Maschinencode des eigentlichen Programmes abspeichere. 
Insofern bezieht sich meine Frage dann nur auf die PICs!

von Jens M. (schuchkleisser)


Lesenswert?

Jürgen K. schrieb:
> Das spart Speicherplatz

Du bekommst kein Geld zurück für nicht gebrauchtes Flash.
Und auf der Festplatte sind es nur wenige hundert Bytes weniger, 
Flashzeit wird ebenfalls nur marginal reduziert.

Jürgen K. schrieb:
> 1. Gibt es bei PIC/ATMEL im Assembler auch absolute
> Sprünge/Sprungadressen?

Na klar.
Liegt am Programmierer und Compiler ob das passiert, aber möglich sind 
sowohl absolute als auch relative Sprünge.

Jürgen K. schrieb:
> 2. Kann ich den eigentlichen Programmcode ab 0400hex einfach an eine
> andere Adresse verschieben?

In der Regel nicht.
Es sei denn du schreibst ihn als Quellcode um. Eben als "relativ", oder 
an eine andere Startsadresse.

Plus:
Es kann sein, das der Bootloader Hardwarehürden umschifft in dem er 
nicht das programmiert was du meinst, will sagen: er patcht das Programm 
um, damit das normalerweise nicht "Bootloader-Aware" erstellte Programm 
"mit" läuft.
Auslesen und neu Programmieren geht dann nicht, weil im zweiten Teil der 
Bootloader fehlt, der z.B. Sprungadressen benutzt.

Aber warum sich das antun?
Du kannst mit jedem Compiler oder Assembler einfach ein Programm 
erstellen und die Hexdatei z.B. via avrdude auch ohne Bootloader 
programmieren, und das tut dann auch, ohne die Sicherheitslücke 
Bootloader und ohne Frickelei mit Auslesen und umpatchen.

von Jens M. (schuchkleisser)


Lesenswert?

Jürgen K. schrieb:
> Das würde bedeuten, dass meine Gedanken nur bei
> den PICs zutreffen würden, da dort der Bootloader vorn (0 - 0400hex)
> liegt.

Nicht zwangsläufig.
Je nach Chip ist der Bootloader oben, aber der Resetvektor wird 
umgepatcht.
Dadurch ist der Bootloader "unsichtbar", das Programm kann mit und ohne 
laufen ohne das es zwei Versionen gibt.
Bei deinem "BL vorne" musst du das Programm entsprechend übersetzen, was 
Fehleranfällig ist.

Bei AVRs stimmen evtl. die Fuses nicht mit/ohne BL. Zum Glück haben die 
PICs das nicht, die Config steht mit im Hexfile, wenn der Programmierer 
kein Volldepp ist.

von Peter D. (peda)


Lesenswert?

Bei den klassischen ATtiny/ATmega muß der Compiler nicht wissen, ob ein 
Bootloader benutzt wird oder nicht. Die Applikation startet immer an 
0x0000.

Bei den neuen AVRs muß man die Applikation verschieben, d.h. der Linker 
muß die Adresse der Applikation kennen. Ansonsten zeigen absolute 
Sprünge und Calls, die Interruptvektoren sowie konstante Daten im Flash 
in den Wald.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jürgen K. schrieb:
> 1. Gibt es bei PIC/ATMEL im Assembler auch absolute
> Sprünge/Sprungadressen?

Selbst wenn keine absoluten Sprünge / Calls verwendet werden bedeutet 
das noch lange nicht, dass der Code relokatibel ist.

Zum Beispiel ein indirekter Funktionsaufruf:  Das Problem ist die 
"Berechnung" der Funktionsadresse; die besteht aus dem Nehmen der 
absoluten Adresse der Funktion.

Dito für indirekte Sprünge, etwa in if/else Dispatch-Tables, Computed 
Goto, Nonlocal Goto (Exceptions), etc.

Eine Möglichkeit, relokatiblen Code zu realisieren ist z.B. ein ELF 
Loader auf dem Device, das zur Load-Zeit entsprechende RELOCs fixt.  Der 
entstehende Code ist dann zwar nicht mehr relokatibel, spielt aber keine 
Rolle, weil bei erneutem Laden die Loader den Code wieder auf die 
gewählte Adresse anpasst.

Für AVR wüsste ich nicht, dass jemand mal auch nur versucht hätte, einen 
ELF-Loader zu schreiben -- wäre auch nicht sonderlich sinnvoll, weil die 
Tools keine entsprechenden RELOCs erzeugen.

Dann gibt es noch die Möglichkeit, echt relokatiblen Code zu erzeugen. 
Aber auch das würde Erweiterungen der Tools erfordern, etwa wie die 
Adresse eines Labels zu berechnen ist.  Weiteres Problem ist, dass es 
keine absoluten Sprünge / Calls geben kann, d.h. man braucht ein 
Branch-Relaxing im Linker, was zB für AVR nicht umsetzbar ist.

: Bearbeitet durch User
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.