Ich bin GCC-Anfänger und programmiere normalerweise in Assembler auf der AVR-Plattform. Ich stehe nun vor der Aufgabe eine Reihe von Funktionen und Berechnungen mit Werten aus zwei oder drei "gleichen" SRAM-Speicherbereichen durchführen zu müssen. In Assembler ist das einfach: Z zeigte auf die jeweilige Basisadresse des Speicherbereiches und über LDD r0,Z+VARIABLE hatte ich den jeweiligen Wert. Wie kann ich ein solches Konstrukt möglichst einfach in GCC programmieren? Bitte eure Antworten gern mit kurzen Beispiel-Code. Ich bin halt Anfänger. Vielen Dank!
Angenommen ich mache ein Array 100 x 2, um die Daten zu indizieren. Die Zeilen (100) sind die Adressen, die Spalten (2) quasi die Speicherbereiche. Wäre das ein praktikabler Weg?
Ich würde das dem GCC überlassen wie er das adressiert. In C kennst du keine SRAM-Zellen, nur Variablen, wo die liegen ist dir egal, das muss nur der Compiler wissen. Hast du mehrere Daten mit unterschiedlichen Typen (z.B. Benutzereinstellungen)? Dann definier dir eine passende Struktur. Adressiert wird über die Member-Namen. Sind die Daten alle vom gleichen Typ, dann nimm ein Array. Addressiert wird das dann über einen Index. Codebeispiele finden sich in jedem C-Buch oder Google. Wenn dir das nicht hilft, solltest du genauer beschreiben was du machen willst.
Andi_07 schrieb: > Angenommen ich mache ein Array 100 x 2, um die Daten zu indizieren. > Die Zeilen (100) sind die Adressen, die Spalten (2) quasi die > Speicherbereiche. > > Wäre das ein praktikabler Weg? IdR ist es nicht möglich, ein Assembler-Programm Befehl für Befehl in ein C-Programm zu übertragen. Stattdessen: 1) Schau dir an, welche Aufgaben das Assembler-Programm löst 2) Mach dich mit der Hochsprache und ihren Konstrukten vertraut und löse die AUfgabe mit diesen Konstrukten. Ein C-Programm dahin zu biegen, daß es die gleichen Instruktionen erzeugt wie ein Assembler-Programm ist nich möglich, und wenn, ist das C-Programm zielmich sicher recht unwartbar und das Ergebnis zudem stark von Compiler-Version und -Einstellungen abhängig. > LDD r0,Z+VARIABLE Solch eine Adressierungsart gibt es nicht. Der Offset bei LDD muss zur Compilezeit bekannt sein; es ist nicht möglich, hier eine Variable (ein Register) hinzuschreiben. Es ist auch nicht möglich, dort ein Symbol (zB die Adresse einer Variable im Static Storage) hinzuschreiben, weil es in avr-Binutils dafür keinen Reloc gibt. Zudem müsste man dann sicherstellen, daß das Symbol immer Werte 0...63 hat. Offsets, die zur Compilezeit bekannt sind, erhält man zB so:
1 | typedef struct |
2 | {
|
3 | char a, b, c; |
4 | } data_t; |
5 | |
6 | char f1 (data_t *d) |
7 | {
|
8 | return d->b + d->c; |
9 | }
|
10 | |
11 | char f2 (char *d) |
12 | {
|
13 | return d[4] + d[20]; |
14 | }
|
15 | |
16 | char f3 (data_t *d) |
17 | {
|
18 | return d[4].c + d[10].b + d[7].a; |
19 | }
|
Weil die Offsets der Strukturkomponenten zur Compilezeit bekannt sind, kann der Compiler diese in LDD verwenden. Gleiches gilt für Arrayzugriffe mit bekannten Indices, und natürlich für beliebige Kombinationen daraus. avr-gcc macht aus dem Code (-S -mmcu=atmega8 -Os):
1 | f1: |
2 | movw r30,r24 |
3 | ldd r25,Z+2 |
4 | ldd r24,Z+1 |
5 | add r24,r25 |
6 | ret |
7 | |
8 | f2: |
9 | movw r30,r24 |
10 | ldd r25,Z+20 |
11 | ldd r24,Z+4 |
12 | add r24,r25 |
13 | ret |
14 | |
15 | f3: |
16 | movw r30,r24 |
17 | ldd r24,Z+31 |
18 | ldd r25,Z+14 |
19 | add r24,r25 |
20 | ldd r25,Z+21 |
21 | add r24,r25 |
22 | ret |
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.