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


von Armin (Gast)


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!

von Thomas (Gast)


Lesenswert?

Weil ein Int 4 Byte lang ist?

von Armin (Gast)


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?

von Rolf Magnus (Gast)


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. ;-)

von Karl H. (kbuchegg)


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.

von Armin (Gast)


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?

von Bernhard (Gast)


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

von Armin (Gast)


Lesenswert?

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


von Thomas (Gast)


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.

von Rolf Magnus (Gast)


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?

von Markus K. (markus-)


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

von Bartli (Gast)


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...

von Armin (Gast)


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!

von Rufus Τ. F. (rufus) Benutzerseite


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?!

von Armin (Gast)


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???

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Armin (Gast)


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!

von Μαtthias W. (matthias) Benutzerseite


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

von Markus K. (markus-)


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

von Μαtthias W. (matthias) Benutzerseite


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

von Markus K. (markus-)


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

von Rolf Magnus (Gast)


Lesenswert?

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

Der muß gar keinen Aufwand treiben.

von Bartli (Gast)


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.

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.