Forum: Mikrocontroller und Digitale Elektronik ASM und C in AVR Studio


von Jan S. (jannemann)


Lesenswert?

Hallo,
habe schon in einem anderen (alten) Thread 
(Beitrag "AVR-Studio C+Assembler mischen" einmal die Frage 
gestellt, da dieser aber scheinbar schon länger tot ist, hier jetzt noch 
einmal in einem neuen Thread

Mir sind im AVR-Gcc Tutorial bei dem Einbinden von Assembler-Dateien 2
Dinge unklar
(http://www.mikrocontroller.net/articles/AVR-GCC-Tu...)

beide Fragen beziehen sich auf die Datei useful.S

1)warum wird hier auf die Register über eine einfache Zahl zugegriffen? 
(siehe workreg=16, workreg2=17, ...) und nicht wie sonst in asm
mit
1
.define workreg r16
 oder
1
equ workreg=$016


2) in der Funktion superfunc:
1
out  _SFR_IO_ADDR(DDRD), workreg
warum kann ich hier nicht direkt auf das DDRD zugreifen? Sondern muss 
das Macro nutzen.
In Assembler würde die Zeile doch eigentlich so aussehen:
1
out  DDRD, r16
Ich habe schon nen bisschen rumgesucht, das ganze scheint nur so zu
laufen, wenn man asm und c mischen will. Aber gute Literatur, die eine
gute Beschreibung und Erklärung liefert, hab ich leider noch nicht
gefunden.

Falls die Entwicklungsumgebung relevant ist: Ich nutze AVR Studio 4.18

Danke im voraus!

von Ratsuchender, der II (Gast)


Lesenswert?

Da schließe ich mich dem Jan S. an.

Wie eine Dokumentation "wie rufe ich C-Funktionen aus Asm-Programmen
auf? (Oder umgekehrt), Werte Übergabe etc. sein könnte findet man in
Keils Beschreibung zum ASM51, leider habe auch ich nichts für den
ATMEGA gefunden.

Vielleicht hat hier im Forum jemand einen guten Rat.

von ... (Gast)


Lesenswert?

Jetzt also doch ein eigener Thread statt Leichen schänden.

zu 1) keine Ahnung warum, aber das 'r' bei Registern kann man (meist?) 
weglassen:
1
out  _SFR_IO_ADDR(DDRD), 16
2
out  _SFR_IO_ADDR(DDRD), r16
geht beides

zu 2) Hängt mit der Architektur der AVRs zusammen. Insbesondere z.B. das 
Register zum Teil über unterschiedliche Adressen und Befehle 
angesprochen werden können und das auch noch vom jeweiligen AVR abhängig 
ist. Siehe:
http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr__notes.html

von Karl H. (kbuchegg)


Lesenswert?

Jan S. schrieb:

> beide Fragen beziehen sich auf die Datei useful.S


und für beide Fragen gibt es im Grunde die gleiche Antwort:

Weil es sich bei diesem Assembler eben nicht um den von Atmel für die 
AVR-Familie geschriebenen Assembler handelt, sondern um den GNU 
Assembler, der mit dem GCC mitkommt.
Dieser Assembler ist aber per se nicht auf eine spezielle Architektur 
ausgerichtet, sondern soll auf allen Architekturen funktionieren. Und 
daher findet sich dort wenig bis gar nichts wieder, so wie es beim 
AVR-Assembler von Atmel funktioniert.

> 1)warum wird hier auf die Register über eine einfache Zahl zugegriffen?

Weil verschiedene Architekturen unterschiedliche Vorstellungen davon 
haben, wie sie ihre Register benennen wollen. Beim AVR heißen die eben 
r1 bis r32, beim Z80 hiessen die A, B, C, D, ... bei wieder einem 
anderen Prozessor eben anders.

Da aber ziemlich klar ist, wann es sich in einem Befehl um ein Register 
handelt, kann man auch ganz einfach diese ganzen Spezialitäten wegfallen 
lassen, und die Register einfach durchnummerieren.

>
> 2) in der Funktion superfunc:
>
1
out  _SFR_IO_ADDR(DDRD), workreg
> warum kann ich hier nicht direkt auf das DDRD zugreifen? Sondern muss
> das Macro nutzen.

Du greifst nach wie vor direkt zu.
Aber das DDRD Register 'existiert' 2-mal. D.h. natürlich gibt es das 
Register nur einmal, aber es gibt 2 mögliche Wege um es anzusprechen: 
Über eine I/O Adresse oder über eine Memory-Adresse. Leider sind aber 
die Zahlenwerte dieser beiden Adressen nicht gleich. Wenn der Assembler 
jetzt grundsätzlich immer und überall Memory-Adressen vorliegen hat, 
dann muss es einen Mechanismus geben, der die Memory-Adresse in eine I/O 
Adresse umrechnet. Genau das macht dieses Makro.

Warum ist das so?
Weil es einige Register in den AVR gibt, die eben per I/O Adressierung 
nicht erreichbar sind. Per Memory ADressierung kommt man an jedes 
Register heran. D.h. der Compiler tut erst mal so, als ob er immer 
mittels Memory-Adressierung an das Register gehen würde. Erst ein 
nachfolgender Optimierungsschritt tauscht das dann gegen IN/OUT Befehle 
aus und klammert die Memor-Adresse mit dem Makro um die entsprechende 
Umrechnung zu erreichen.

von Jan S. (jannemann)


Lesenswert?

Das sollte meinen Wissendurst für erste stillen.
Dankeschön

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.