Forum: Compiler & IDEs Pointer in AVRGCC


von Sebastian (Gast)


Lesenswert?

Hallo zusammen...

Ich benutze den neusten AVRGCC von winavr.sourcefroge.net und AVR
Studio 4. Ich habe einen Pointer, zwei structs und zwei pointer auf
diese structs:
#define BUF_SIZE 384
unsigned char buf[BUF_SIZE];

struct eth_hdr {
  u08 dst_mac[6];
  u08 src_mac[6];
  u16 typ;
};
struct eth_hdr* eth_hdr;

struct ip_hdr {
  u08  ver_ihl;  // 4 byte: Version + 4 byte: Internet Header Length
  u08  tos;    // Type of Service
  u16  len;    // Total Length in octets
  u16  id;    // Indentification
  u16 frag;    // 3 bytes: Flags + 13 bytes: Fragment Offset
  u08  ttl;    // Time to Live
  u08 proto;    // Protocol:
#define PROTO_UDP  17
  u16  check;    // Header Checksum
  u32  src_ip;    // Source IP
  u32 dst_ip;    // Destination IP
};
struct ip_hdr* ip_hdr;

Dann möchte ich gerne folgendes machen:
eth_hdr = (struct eth_hdr*) buf;
ip_hdr  = (struct ip_hdr*)  eth_hdr+sizeof(struct eth_hdr);

Wobei aus der zweiten Zeile wird:
+0000007A:   918001EC    LDS     R24,0x01EC       Load direct from data
space
+0000007C:   919001ED    LDS     R25,0x01ED       Load direct from data
space
+0000007E:   5E88        SUBI    R24,0xE8         Subtract immediate
+0000007F:   4F9E        SBCI    R25,0xFE         Subtract immediate
with carry
+00000080:   939001EB    STS     0x01EB,R25       Store direct to data
space
+00000082:   938001EA    STS     0x01EA,R24       Store direct to data
space

Nur wenn ich es so schreibe:
ip_hdr  = (struct ip_hdr*)  ((u16) eth_hdr+sizeof(struct eth_hdr));

wird es korrekt übersetzt zu:
+00000084:   918001EA    LDS     R24,0x01EA       Load direct from data
space
+00000086:   91900000    LDS     R25,0x0000       Load direct from data
space
+00000088:   9644        ADIW    R24,0x14         Add immediate to
word
+00000089:   93900067    STS     0x0067,R25       Store direct to data
space
+0000008B:   93800066    STS     0x0066,R24       Store direct to data
space


Hätte da jemand einen Tipp für mich, denn normalerweise sollte es die
erste Variante doch problemlos tun, oder?

Danke schonmal
  Sebastian.

von Karl H. (kbuchegg)


Lesenswert?

Nicht wirklich.
Bei Pointer-Arithmetik wird immer implizit mit dem Datentyp
auf den der Pointer zeigt multipliziert. Wenn das nicht
so wäre würde die ganze Array Indizierung nicht gehen.

Du hast 2 Möglichkeiten:

* ip_hdr  = (struct ip_hdr*)  eth_hdr+1;

* ip_hdr  = (struct ip_hdr*) ((unsigned char*)eth_hdr)+sizeof(struct
eth_hdr);

von Karl H. (kbuchegg)


Lesenswert?

> * ip_hdr  = (struct ip_hdr*)  eth_hdr+1;

Ooops. Da fehlt eine Klammer:

* ip_hdr  = (struct ip_hdr*)  (eth_hdr+1);

von Karl H. (kbuchegg)


Lesenswert?

Schlecht geschrieben:
Der * am Anfang der Zeile ist als Aufzählungszeichen zu lesen
und hat nichts mit dem Quellcode zu tun.

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.