www.mikrocontroller.net

Forum: PC-Programmierung Zeiger in C auf einem 32-Bit System


Autor: Armin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum reserviert C bei einem Integer-Zeiger  4 Adressen und nicht eine 
einzige Adresse ( 32-Bit breiter Datenbus )?
Gibt es einen 8-Bit bzw. 32-Bit Modus?
Wie kann ich zwischen den beiden Moden umschalten?

System:    PC104 Cool LiteRunner
Betriebssystem:   Linux Kernel 2.6.16 mit Xenomai Patch
Prozessor:     AMD GX 466

Warscheinlich werden sich jetzt einige an den Kopf fassen und sagen man 
ist der doof :-) aber das kenn ich auch.
Danke schon mal!

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil ein Int 4 Byte lang ist?

Autor: Armin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist mir auch klar 4 Byte enthalten doch 32 Bit, also müsste doch eine 
Adresse auf einem 32-Bit System ausreichen. Oder leben wir immer noch in 
einer 8-Bit Welt und reden alle von 32 und 64?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Warum reserviert C bei einem Integer-Zeiger  4 Adressen und nicht eine
> einzige Adresse ( 32-Bit breiter Datenbus )?

Verstehe nicht, was du meinst. Wo werden 4 Adressen reserviert? Ein 
Zeiger kann nur die Adresse eines einzelnen Objekts enthalten. Er hat 
auch nur eine Adresse.

> Gibt es einen 8-Bit bzw. 32-Bit Modus?

Nein. Was soll der denn machen?

> Warscheinlich werden sich jetzt einige an den Kopf fassen und sagen man
> ist der doof :-)

Nein. Man wird ja nicht allwissend geboren. Ich kratz mich nur am Kopf 
und versuche, die Frage zu verstehen. ;-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ZUnächst mal sollten wir klären, wie du
zu der Aussage 'es werden 4 Adressen reerviert' kommst.

Ein Zeiger belegt auf einem 32 Bit System meistens 4 Byte.
Ein int belegt in einem 32 Bit System ebenfalls 4 Byte.

Auch wenn du auf einem 32 Bit System bist, die kleinste
addressierbare Einheit ist immer noch das Byte.

Autor: Armin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kleines Beispiel was ich meine:

#include<stdio.h>

main()
         {
    int i;
    int mem[5];

    for (i=0; i < 5; i++)
      printf("adr: %x\n", &mem[i]);

          }

Ausgabe:

adr: bfcf40c0
adr: bfcf40c4
adr: bfcf40c8
adr: bfcf40cc
adr: bfcf40d0

Wie man erkennt beträgt das Inkrement 4. Da ich aber eigentlich einen 
32-Bit Datenbus habe sollte doch ein Inkrement von 1 ausrechend für 
einen Integer sein.
Oder sehe ich da etwas falsch?

Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das siehste grottenfalsch. Die kleinste_ _adressierbare_ _Einheit 
bei diesem System ist - wie bei vielen anderen auch - das Byte (8 Bit). 
Ein Integer ist bei diesem Compiler 32 Bit lang, benötigt also 4 Bytes. 
Dementsprechend ist die Adress-Differenz zwischen zwei 
aufeinanderfolgenden Elementen dieses Arrays genau 4. Probiere das Ganze 
mit short aus; Du wirst ein Inkrement von 2 erhalten; bei char sinkt das 
Inkrement auf 1.

Bernhard

Autor: Armin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok wenn dem so ist, dann kann aber die Adresse die ich in diesem 
Beispiel erhalte keine real existierende Adresse sein.?


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Egal, ob du auf einem 32- oder 16- Bit Rechner arbeitest, kannsst du 
jedes Byte separat ansteuern. Dass die CPU und der RAM gleich 2 bzw 4 
davon verarbeiten könnem ist dafür ohne Belang.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die kleinste_ _adressierbare_ _Einheit bei diesem System ist - wie
> bei vielen anderen auch - das Byte

Kunststück. So ist das Byte in der Regel definiert.

> (8 Bit).

Das meistens auch, ja.

@Armin:

Überlege mal: Wenn bei int das Inkrement 1 ist, wie groß müßte es dann 
für Typen sein, die kleiner als int sind?

Autor: Markus K. (markus-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Armin wrote:
> Ok wenn dem so ist, dann kann aber die Adresse die ich in diesem
> Beispiel erhalte keine real existierende Adresse sein.?

Das ist nicht die Adresse auf dem Adressbus, sondern eben die 
Byte-Adresse.

Du kannst auf den meisten 32Bit-CPUs auch einen 32bit-Wert an die 
Byte-Adresse 3 schreiben, dann muss die CPU daraus unter Umständen eben 
zwei Speicherzugriffe machen.

Es gibt auch 32Bit-CPUs, bei denen das Speicherinterface schmäler oder 
breiter als 32Bit ist. Beim 386sx hat es nur 16Bit, beim Pentium dagegen 
64Bit.

bye
  Markus

Autor: Bartli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Du kannst auf den meisten 32Bit-CPUs auch einen 32bit-Wert an die Byte-Adresse 3 
schreiben

Da hätt ich jetzt gesagt, dass man das bei den meisten Architekturen 
genau nicht kann...

Autor: Armin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal euch allen.
Mein eigentliches Problem ist, dass ich auf einen RAM Baustein (16-Bit) 
am ISA-Bus zugreifen möchte. Mit dem folgenden kleinen Programm versuch 
ich den RAM auszulesen. Leider erhalte ich nicht alle im RAM enthaltenen 
Werte.

#define BASIS 0xc8000
main()
  {
    int i;
    short mem[32];

    int fd = open("/dev/mem", O_RDWR);

    short *virtbase = mmap(0, 1024, PROT_READ | PROT_WRITE,
      MAP_SHARED, fd, BASIS);

    for (i=0; i < 8; i++){
      mem[i] = virtbase[i];
      //printf("virtbase: %x\n", virtbase[i]);
      }

    for (i=0; i < 8; i++)
      printf("mem: %x\n", mem[i]);
  }

Ergebnis:
mem: 1201
mem: 1403
mem: 1605
mem: 1807

Im RAM entahlten:
 0x1101;
 0x1202;
 0x1303;
 0x1404;
 0x1505;
 0x1606;
 0x1707;
 0x1808;

Wenn ich virtbase und mem als char definiere und das printf nicht 
auskommentiere erhalte ich folgendes Ergebnis:
virtbase: 1
virtbase: 12
virtbase: 3
virtbase: 14
virtbase: 5
virtbase: 16
virtbase: 7
virtbase: 8
mem: 1
mem: 2
mem: 3
mem: 4
mem: 5
mem: 6
mem: 7
mem: 8

Hat jemand eine Idee wie ich richtig an die Daten komme?
Danke!

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine ISA-Karte ist nicht in Ordnung. Anscheinend ist sie nicht in der 
Lage, korrekte 8-Bit-Speicherzugriffe durchzuführen. Das Problem liegt 
vermutlich irgendwo in der Gegend der Erzeugung des Signales /MEMCS16.

Woher weißt Du, was im RAM enthalten sein soll?

Bist Du Dir sicher, daß

    short *virtbase = mmap(0, 1024, PROT_READ | PROT_WRITE,

etc. den korrekten Adressbereich der ISA-Karte angibt? RAM auf Adresse 
0?!

Autor: Armin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das /MEMCS16 Signal wir erzeugt, allerdings etwas später als eigentlich 
nötig. Da ich aber gelesen habe, dass wenn das /MEMCS16 etwas später 
also wärend des 8-Bitlesevorgangs erzeugt wird, wird ein weiterer 
Lesevorgang im selben Zyklus durchgeführt. Dies hab ich auch mit Hilfe 
eines Qszis nachgeprüft. Kann aber natürlich nicht außschließen, dass 
dies Probleme bereitet. Wie kann ich eventuell beweisen, dass es sich um 
ein Probleme bei der Karte handelt?

Ich weiß was in dem RAM enthalten ist, da es ein V-RAM ist, in den ich 
mit einem PIC ( leider kein Atmel (hat Vor- und Nachteile)) Werte 
hineinschreibe.

Ich bin mir inzwischen bei garnichts mehr sicher :-).

#define BASIS 0xC8000
short *virtbase = mmap(0, 1024, PROT_READ | PROT_WRITE,
      MAP_SHARED, fd, BASIS);

void  *  mmap(void *start, size_t length, int prot , int flags, int fd,
       off_t offset);

Die Basisadresse des RAMS ist bei 0xC8000. Die Endadresse ist 0xC83FF.
Wenn ich den Befehl richtig verstanden hab, dann wird der Seicherbereich 
ab offset nach start abgebildet. Lieg ich da ganz falsch???

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, das mit der Adresse könnte funktionieren. Wenn das Motherboard an 
der betreffenden Adresse nicht versehentlich RAM oder ein anderes ROM 
einblendet - hast Du mal unter DOS* mit einem Debugger nachgesehen?


*) damit meine ich NICHT die Windows-Eingabeaufforderung, sondern MS-DOS 
als "Betriebssystem". Also kein Windows, auch kein Windows 95 oder 3.11.

Autor: Armin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Problem teilweise gelöst. Hab festgestellt, dass es im 8-Bit Modus 
funktioniert. Ist wohl doch ein Problem mit dem Timing auf dem ISA-Bus.
Danke rufus!
Danke euch allen!

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bartli wrote:
>> Du kannst auf den meisten 32Bit-CPUs auch einen 32bit-Wert an die Byte-Adresse 
3 schreiben
>
> Da hätt ich jetzt gesagt, dass man das bei den meisten Architekturen
> genau nicht kann...

Welche 32Bit-Architekturen können das denn überhaupt? Mir fällt da auf 
Anhieb nur eine ein (die wohlbekannte aus Santa Klara, Kalifornien) und 
selbst dort sollte man solche Aktionen der Performance wegen lieber 
bleiben lassen.

Matthias

Autor: Markus K. (markus-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias Weißer wrote:
> Bartli wrote:
>>> Du kannst auf den meisten 32Bit-CPUs auch einen 32bit-Wert an die Byte-Adresse 
3 schreiben
>>
>> Da hätt ich jetzt gesagt, dass man das bei den meisten Architekturen
>> genau nicht kann...

Ich geb' zu, das war eher so ein Gefühl, ich habe nicht wirklich eine 
Übersicht über die CPUs, die das können.

> Welche 32Bit-Architekturen können das denn überhaupt? Mir fällt da auf
> Anhieb nur eine ein (die wohlbekannte aus Santa Klara, Kalifornien) und

z.B. PPC:
"Although the best performance results from the use of aligned accesses, 
the PowerPC architecture is unusual among RISC architectures in that it 
permits misaligned data accesses."

und ARM ab Architektur ARMv6 (ARM11)

> selbst dort sollte man solche Aktionen der Performance wegen lieber
> bleiben lassen.

Das ist klar, aber ich wollte nur darauf hinweisen, dass Adressen im 
Programm und der Adressbus zweierlei sind.

Markus

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus Kaufmann wrote:
> Matthias Weißer wrote:
>> Welche 32Bit-Architekturen können das denn überhaupt? Mir fällt da auf
>> Anhieb nur eine ein (die wohlbekannte aus Santa Klara, Kalifornien) und
>
> und ARM ab Architektur ARMv6 (ARM11)

Die haben das echt eingebaut? Naja evtl. gibt es tatsächlich ARM-Systeme 
die etwas knapp an Speicher sind.

>> selbst dort sollte man solche Aktionen der Performance wegen lieber
>> bleiben lassen.
>
> Das ist klar, aber ich wollte nur darauf hinweisen, dass Adressen im
> Programm und der Adressbus zweierlei sind.

Genau. Um den eigentlichen Adressbus kümmert sich ein Hardwerker :-)

Matthias

Autor: Markus K. (markus-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias Weißer wrote:
> Markus Kaufmann wrote:
>> Matthias Weißer wrote:
>>> Welche 32Bit-Architekturen können das denn überhaupt? Mir fällt da auf
>>> Anhieb nur eine ein (die wohlbekannte aus Santa Klara, Kalifornien) und
>>
>> und ARM ab Architektur ARMv6 (ARM11)
>
> Die haben das echt eingebaut?

Ich hatte damit noch nichts zu tun, aber der englische Wikipedia-Artikel 
zur ARM-Architektur sagt:
"No support for misaligned memory accesses (now supported in ARMv6 
cores)"

> Naja evtl. gibt es tatsächlich ARM-Systeme
> die etwas knapp an Speicher sind.

Kann ich mir nicht wirklich vorstellen. Verbaut sind diese CPUs 
angeblich in Nokia N93, Zune und Nokia N800.

Ich verstehe aber nicht, wieso das nicht mehr CPUs haben. Transistoren 
sind heutzutage ja nicht mehr so teuer wie früher und das externe RAM 
ist bei großen CPUs ja eh weit weg (von der Logik her) und der Aufwand, 
den sonst der Compiler treiben muss macht das System ja auch nicht 
schneller.

Markus

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> und der Aufwand, den sonst der Compiler treiben muss macht das System
> ja auch nicht schneller.

Der muß gar keinen Aufwand treiben.

Autor: Bartli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Verbieg dir doch auf nem System welches nur auf ausgerichtete Adressen 
zugreifen kann z.B. einen int* auf eine ungerade Adresse und lies davon 
- der Compiler wird dir das kompilieren, aber funktionieren wirds nicht.

=> Null Aufwand auf der Compilerseite.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.