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!
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?
> 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. ;-)
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.
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?
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
Ok wenn dem so ist, dann kann aber die Adresse die ich in diesem Beispiel erhalte keine real existierende Adresse sein.?
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.
> 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?
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
> 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...
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!
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?!
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???
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.
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!
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
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
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
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
> und der Aufwand, den sonst der Compiler treiben muss macht das System > ja auch nicht schneller. Der muß gar keinen Aufwand treiben.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.