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.