Hallo, ich programmiere mit dem AVR-Studio4 einen ATtiny in C Jetzt will ich in dem C Programm eine kleine Bitnapperei :-) in Assembler mit reinbringen. Es sollen zwei long int Werte übergeben werden und ein long int Wert soll von dem Assembler-Teil an C wieder zurückgegeben werden. Jetzt weiss ich nicht, 1. Wie kann ich C und Assembler zusammenbringen? 2. Wie kann ich long int Werte übergeben und zurückgeben? Da gibt's doch bestimmt ein Tutorial, oder hat jemand ein Beispiel :-) für mich?
>Da gibt's doch bestimmt ein Tutorial Oder ein Manual, nämlich von WinAVR bzw. vom GCC... AVRStudio ist nur die IDE.
Inline Assembler http://www.rn-wissen.de/index.php/Inline-Assembler_in_avr-gcc http://www.nongnu.org/avr-libc/user-manual/inline__asm.html Seperate Assembler Dateien Würde ich mir eine entsprechende Dummy/Stub C-Funktion nach ASM übersetzen lassen und den produzierten Code für den Funktionsrumpf als Vorlage für die eigene ASM Funktion benutzen.
Graue Maus schrieb: > Jetzt will ich in dem C Programm eine kleine Bitnapperei :-) in > Assembler mit reinbringen. Und Du bist sicher, daß es auch den höheren Aufwand, die schlechtere Wartbarkeit, Erweiterbarkeit und Portabilität wert ist? Meine Erfahrungen bezüglich Assembler und C mixen endeten immer mit der Erkenntnis: Laß es sein. Schade um die damit vergeudete Zeit. Peter
Peter Dannegger schrieb: > Laß es sein. Nö ;-) Hat mal jemand ein schönes Inline-Assembler-Beispiel?
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Inline-Assembler -- viel schöner wird's nicht
Also der Einwand abzuschätzen obs die Zeit und Nerven wert ist, der ist nicht ganz aus der Luft gegriffen. Asm Funktionen einbinden kostet durch Register sichern schon merklich overhead, wenns nur um etwas bit nappen geht. Das ist u.U. nicht mal schneller, als kontrolliert in c programmiert. Meine Meinung. Als rein akademische Übung, ok das ist was anderes. Das "Nö ;-)" kann ich nciht deuten, ob eben schnippisch "nö, und doch!" oder "nö, einfach mal ausprobieren" gemeint ist.
Ich habe festgestellt, das der Compiler manchmal "a bisserl umständlich" zu Werke geht. Z.B.
1 | //PB3 soll low-Puls & PB4 soll high-Puls ausgeben |
2 | PINB = (1 << PIN3) | (1 << PIN4); |
3 | 58: e6 e3 ldi r30, 0x36 ; 54 |
4 | 5a: f0 e0 ldi r31, 0x00 ; 0 |
5 | 5c: 88 e1 ldi r24, 0x18 ; 24 |
6 | 5e: 80 83 st Z, r24 |
7 | PINB = (1 << PIN3) | (1 << PIN4); |
8 | 60: e6 e3 ldi r30, 0x36 ; 54 |
9 | 62: f0 e0 ldi r31, 0x00 ; 0 |
10 | 64: 88 e1 ldi r24, 0x18 ; 24 |
11 | 66: 80 83 st Z, r24 |
Ich würd es da in Assembler so machen:
1 | //PB3 soll low-Puls & PB4 soll high-Puls ausgeben |
2 | PINB = (1 << PIN3) | (1 << PIN4); |
3 | 58: e6 e3 ldi r30, 0x36 ; 54 |
4 | 5a: f0 e0 ldi r31, 0x00 ; 0 |
5 | 5c: 88 e1 ldi r24, 0x18 ; 24 |
6 | 5e: 80 83 st Z, r24 |
7 | PINB = (1 << PIN3) | (1 << PIN4); |
8 | 60: 80 83 st Z, r24 |
kann es das das der asm code nicht zum Kommentar passt? Denn wo ist das out wenn man dem Port etwas zuweist? Und bei deiner Optimierung steht am ende 2 mal st Z, r24 st Z, r24 das macht auch wenig sinn.
Graue Maus schrieb: > Ich habe festgestellt, das der Compiler manchmal "a bisserl umständlich" > zu Werke geht. Z.B.... Komisch. Hast du etwa die Optimierung ausgeschaltet? Mein AVR-GCC macht aus
1 | PINB = (1 << PIN3) | (1 << PIN4); |
2 | PINB = (1 << PIN3) | (1 << PIN4); |
folgendes:
1 | ldi r24,lo8(24) |
2 | out 54-0x20,r24 |
3 | out 54-0x20,r24 |
Hi > st Z, r24 > st Z, r24 >das macht auch wenig sinn. Doch, da in Z die Portadresse steht. MfG Spess
spess53 schrieb: > Doch, da in Z die Portadresse steht. ich hätte gedacht das man auf die Port nur über out zugreifen kann, ich hatte noch nie gesehen das der compiler dafür das Z Register nutzt - finde ich ein wenig merkwürdig. Es macht auch überhaupt kein sinn erst ein 16Bit register zu laden wenn man es mit out machen kann.
Εrnst B✶ schrieb: > Komisch. Hast du etwa die Optimierung ausgeschaltet? Wo schalte ich die denn ein (und aus)?
Graue Maus schrieb: > Εrnst B✶ schrieb: >> Komisch. Hast du etwa die Optimierung ausgeschaltet? > > Wo schalte ich die denn ein (und aus)? Menüpunkt "Project". Subpunkt "Options" Im unteren Drittel des Dialogs gleich auf der ersten Seite. -O0 ist "aus" -Os ist gebräuchlich und meist ein guter Kompromiss -O3 ist manchmal besser
Peter schrieb: > spess53 schrieb: >> Doch, da in Z die Portadresse steht. > > ich hätte gedacht das man auf die Port nur über out zugreifen kann, ich > hatte noch nie gesehen das der compiler dafür das Z Register nutzt - > finde ich ein wenig merkwürdig. Es macht auch überhaupt kein sinn erst > ein 16Bit register zu laden wenn man es mit out machen kann. Der Compiler benutzt für alles immer zuerst Speicherzugriffe. Erst im nachhinein wird entschieden, welche Zugriffe auf Portbefehle umgemappt werden sollen. Für >90% des Compilercodes ist ein Port daher einfach nur eine Speicherzelle, eine Variable an einer fixen Adresse und kann wie diese in allen Optimierungen behandelt werden. -> Compiler wird dadurch einfacher, weil es einen Sonderfall weniger zu berücksichtigen gibt.
Hi
>ich hätte gedacht das man auf die Port nur über out zugreifen kann,...
Nein, das geht auch über Z. Genauso kannst du auch auf r0...r31
zugreifen.
MfG Spess
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.