Forum: Compiler & IDEs AVR, GCC, Indizierte Adressierung


von Andi_07 (Gast)


Lesenswert?

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!

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Eine Struktur?

von Andi_07 (Gast)


Lesenswert?

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?

von André A. (nummer5) Benutzerseite


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.