Ein Bekannter meint weil er einen 16-Bit-Mikrocontroller verwendet und daran einen 16-Bit-Datenbus hat sind bei ihm die Bytes alle 16 Bit groß. Der C-Standard (C99) sagt dazu nur "A byte is composed of a contiguous sequence of bits, the number of which is implementation-defined.", so das es prinzipiell möglich wäre. Deshalb habe ich nachgesehen mit (*(volatile uint32_t*)(1234)) = 0x00000000; (*(volatile uint16_t*)(1234)) = 0xaaaa; first_byte = (*(volatile uint8_t*)(1234)) second_byte = (*(volatile uint8_t*)(1235)) und es zeigte sich das 16-Bit-Werte sich über zwei Bytes erstrecken, also ein Byte auch dort 8 Bit hat, weil first_byte und second_byte den Wert 0xaa haben (und die zwei nachfolgenden Bytes Null sind). Trotzdem stellen sich zwei Fragen: Wie kann man die Bytegröße (in Bit) automatisch bestimmen; hat jemand eine fertige C-Funktion oder ein Makro dafür? Gibt es überhaupt ein Beispiel für eine Plattform mit C-Compiler, auf der ein Byte ungleich 8 Bit hat und wenn ja, findet man das auch außerhalb von Museen? Wenn ja, dann wäre C ja sehr wenig portabel, denn es gibt daneben ja noch die plattformabhängige Endianess.
Erwin Meyer schrieb: > Wie kann man die Bytegröße (in Bit) automatisch bestimmen; gar nicht. Im Header Limits.h gibt es eine Konstante CHAR_BIT, die sagt es dir Wobei das genaugenommen nicht das ist wonach du fragst. Es handelt sich um die Anzahl der Bits in einem char. Üblicherweise ist ein char (bzw unsigned char) in C gleichzusetzen mit einem "Byte", in dem Sinne als es der kleinste Datentyp ist, den du integral ansprechen kannst. Per Defintion hat ein Byte in C mindestens 8 Bit. Auf einem System, welches CHAR_BIT gleich 16 hat, besteht ein char dann eben aus 2 8-Bit Byte. Allerdings ist auch auf solchen Systemen der sizeof(char) gleich 1, sodass man aus C-Sicht ein C-Byte als 16-Bit Einheit ansehen könnte obwohl es im Speicher meistens aus 2 8-Bit Bytes zusammengebaut wird. Heutige Speicher und Bussysteme sind als Vielfaches von 8 auf den Datenleitungen aufgebaut.
Dein Freund meint wahrscheinlich das ein integer 16 bit groß ist. Das war nämlich wirklich historisch so das die größe eines Int mit der breite des Datenbusses skaliert war. Der bruch kam dann erst bei Einführung der 64bit Systeme. Ein Byte hingegen kenne ich überall nur als 8bit groß (wenn man mal von historischen ausnahmen, die aber nicht mehr verwendet weren, absieht). Die größe eines Int kannst du bestimmen indem du mal in limits.h (wenn es verfügbar ist) reinschaust. Dort stehen die maximalen Werte für unsigned Variablen. Ansonsten würe ich ein long int als Zählvariable nehmen und dann parallel ein int solange hochzählen bis es zum überlauf kommt und schauen welcher wert in meinem long steht.
Erwin Meyer schrieb: > Gibt es überhaupt ein Beispiel für eine Plattform mit C-Compiler, auf > der ein Byte ungleich 8 Bit hat, und wenn ja, findet man das auch > außerhalb von Museen? Was sich heute noch findet sind Maschinen, die nicht durchweg Bytes adressieren, sondern ggf. Worte, und folglich das Byte als Grundeinheit der Adressierung nicht existiert. Zumindest anfangs bot sich das bei DSPs an, wie es da heute aussieht weiss ich aber nicht. Ein ziemlicher Exot ist der recht neue MaxQ2000. Der adressiert 8-Bit Bytes wenn man Bytes meint und 16-Bit Worte wenn man Worte meint. Die Adresse des ersten Bytes eines Wortes ist also das doppelte der Adresse des Wortes. Und weil das eine 16-Bit Architektur ist lässt sich nur die erste Hälfte des Adressraumes als Bytes adressieren. Ich kann mir angenehmeres vorstellen, als ausgerechnet dafür einen C Compiler zu basteln - gibt es aber. Da wird jeder pointer type cast zum Alptraum. Früher gab es beispielsweise 36-Bit und 60-Bit Maschinen, die ganze oder halbe Worte adressierten. Ein natürliches Byte gab es da nicht, auch keine Befehle dafür, und da diese Kisten nur für Berechnungen da waren hat man gerne 6-Bit Zeichensätze verwendet und auf Kleinschreibung verzichtet. Zeichenverarbeitung fand entweder wortweise statt und wenn man partout an einzelne Zeichen eines Strings ran wollte, dann musste notfalls dividiert werden. Den 60-Bittern hat man bald auch alternativ 8-Bit Bytes zugemutet - man hätte sich da also beide Varianten aussuchen können. Von einem C Compiler auf solch einer Kiste ist mir aber nichts bekannt, deren Zeit war abgelaufen als C populär wurde. > Wenn ja, dann wäre C ja sehr wenig portabel, denn es gibt daneben ja > noch die plattformabhängige Endianess. Die Endianess ist ein weitgehend sprachunabhängiges Problem. Sobald man binär codierte Datenstrukturen austauscht hat man eine Konvention am Hals. Egal in welcher Sprache. Da die network byte order big-endian ist und die meisten Maschinen heute little-endian sind hat man das Problem auch sozusagen festgeschrieben.
Also ich formuliere es hoffentlich klarer hiermit: Wieviel Bits liegen
an einer Adresse, und nur unter dieser einen?
Wenn ich einen Speicherbereich über memset mit 0x00 fülle, wieviele (auf
binär 1 gesetzte) Bits muss ich dann an eine Speicherstelle schreiben,
bis die Bits auch in irgendeine andere Speicherstelle geraten?
Der Standard bietet ja Datentypen wie uint8_t, mit dennen man nachmessen
kann.
Karl Heinz Buchegger schrieb:
> Im Header Limits.h gibt es eine Konstante CHAR_BIT, die sagt es dir.
Das passt nicht ganz: Der verwendete Compiler von Keil hat mit C99 nur
entfernt zu tun; es ist ein prä-C90-Kompiler, und zudem geht es nicht um
die Größe eines Bytes mit dem der C-Code arbeitet, z. B. in Form von
char-Variablen, sondern die Größe eines Bytes im Speicher, den der Code
verwendet. Das sind ja zwei ganz verschiedene Sachen meint der Bekannte.
Daneben gibt es auch noch eine dritte Sorte Bytes und zwar die
Speicherworte, die bei einem 16-Bit-Datenbus tatsächlich 16 Bit haben.
Bei der C-Programmierung ist das aber egal, außer bei Performance- und
Alignment-Fragen.
wie lange byte, int oder long ist, läßt sich aus der Compilerbeschreibung ergründen und nur dort:)
Erwin Meyer schrieb: > Also ich formuliere es hoffentlich klarer hiermit: Wieviel Bits liegen > an einer Adresse, und nur unter dieser einen? Also formuliere ich es hoffentlich klarer hiermit: Beim MaxQ2000 hängt es davon ab, ob du grad mit Bytes oder mit Worten arbeitest. Bei Bytes sind es 8 und bei Worten sind es 16, da sich die Adresse zweier aufeinander folgender Bytes ebenso wie die Adresse zweier aufeinander folgender Worte nur um 1 unterscheidet und nicht jeder Teil des Datenspeichers für Bytes verwendbar ist. M.a.W: Es gibt bei diesem auch in anderer Hinsicht sehr schrägen Vogel keine universelle Adresskonvention, also lässt sich die Frage nicht eindeutig beantworten.
Weil auf verschiedenen Maschinen die Größe des int immer anders ist, hab ich mir das hier angewöhnt:
1 | #include <inttypes.h> |
2 | |
3 | uint8_t meine_8bit_unsigned_variable; |
4 | int16_t meine_16bit_signed_variable; |
Seitdem kämpfe ich nicht mehr mit Abbruchkriterien von Schleifen und Bedingungen, nur weil irgendwie da oben nochmal soviel Bits dranhängen, als ich mir gedacht hab'(und eines davon aus unerwünschtem Grund 1 ist). Macht den Code obendrein angenehmer lesbar. Dieses Runter-ver-&-en mit 0xFF und Herum-cast-en muss nicht sein. mfg mf
A. K. schrieb: > Ein ziemlicher Exot ist der recht neue MaxQ2000. Der adressiert 8-Bit > Bytes wenn man Bytes meint und 16-Bit Worte wenn man Worte meint. Die > Adresse des ersten Bytes eines Wortes ist also das doppelte der Adresse > des Wortes. Und weil das eine 16-Bit Architektur ist lässt sich nur die > erste Hälfte des Adressraumes als Bytes adressieren. Ich kann mir > angenehmeres vorstellen, als ausgerechnet dafür einen C Compiler zu > basteln - gibt es aber. Da wird jeder pointer type cast zum Alptraum. Dann ist die Programmiersprache aber kein C, denn wenn ich einem Objekt einen Wert zuweise oder auslese ist das in C unabhängig davon ob es mit einem 8- oder 16-Bit-Zugriff oder sonstwie geschieht, bespielsweise beim Verwenden von memcpy, das ja 8- wie 16-Bit-Werte verwenden kann. Die Hardware kann ja rumrechchnen wie sie will, aber der Compiler hat dafür zu sorgen das Unterschiede zwischen 8- und 16-Bitadressierung transparent sind, sich also nicht auf den C-Code auswirken können. Sonst könnte man ja gleich in Assembler programmieren.
Erwin Meyer schrieb: > Dann ist die Programmiersprache aber kein C Ich beschrieb die Maschine, nicht die Implementierung eines Compilers. Du selbst schriebst ja auch: "und zudem geht es nicht um die Größe eines Bytes mit dem der C-Code arbeitet, z. B. in Form von char-Variablen, sondern die Größe eines Bytes im Speicher". Und damit reduziert es sich auf die Frage, wie gross ein Byte in einem Speicher ist, der keine Bytes kennt (bzw. nicht überall). Eine Antwort darauf kennt allenfalls der Compiler, nicht der Speicher.
Erwin Meyer schrieb: > Sonst könnte man ja gleich in Assembler programmieren. Ist der Grund, warum sich viele Menschen beim AVR gleich für ASM entscheiden ;-)
A. K. schrieb: > Erwin Meyer schrieb: > >> Also ich formuliere es hoffentlich klarer hiermit: Wieviel Bits liegen >> an einer Adresse, und nur unter dieser einen? > > Also formuliere ich es hoffentlich klarer hiermit: Beim MaxQ2000 hängt > es davon ab, ob du grad mit Bytes oder mit Worten arbeitest. Bei Bytes > sind es 8 und bei Worten sind es 16, da sich die Adresse zweier > aufeinander folgender Bytes ebenso wie die Adresse zweier aufeinander > folgender Worte nur um 1 unterscheidet und nicht jeder Teil des > Datenspeichers für Bytes verwendbar ist. Also selbst wenn es sowas gibt, ist die Antwort meine Frage auch hier klar: Bei mehr als 9 Bit zeigen sich Bits auch an einer anderen Adresse und damit ist beispielsweise ein Speicherbereich von 0x1000 bis 0x2000 mit memset(0, 0, 0x1000) zu initialisieren, ganz egal ob das über 8- oder 16-Bit-Zugriffe erfolgt.
Erwin Meyer schrieb: > Also selbst wenn es sowas gibt, ist die Antwort meine Frage auch hier > klar: Bei mehr als 9 Bit zeigen sich Bits auch an einer anderen Adresse Eben nicht. Die zweite Hälfte des Datenadressraums kennt keine Adressen von 8-Bit Objekten, sondern nur Adressen von 16-Bit Objekten. An der (Wort-) Adresse 0x8000 kann sich der Wert 0x1111 befinden und an der Adresse 0x8001 der Wert 0x2222. Folglich zeigen sich dort erst ab 17 Bits welche an der nächsten Adresse. Definiert man "Byte" als kleinste mit einer eindeutigen Adresse versehenden Einheit eines Speichersystems, dann ist das Byte in der ersten Hälfte des Datenraums 8 Bits und in der zweiten Hälfte 16 Bits gross. ;-) Dass Maxim natürlich trotzdem von 8-Bit Bytes redet und sich die Sache in C sicherlich etwas anders darstellt als auf der Hardwareebene ist ein anderes Thema.
Albert ... schrieb: > Das > war nämlich wirklich historisch so das die größe eines Int mit der > breite des Datenbusses skaliert war. Der bruch kam dann erst bei > Einführung der 64bit Systeme. Kennt jemand irgendeine real existierende C-Implementierung, bei der die Größe eines int kleiner ist als 16 Bit?
Rufus Τ. Firefly schrieb: > Kennt jemand irgendeine real existierende C-Implementierung, bei der die > Größe eines int kleiner ist als 16 Bit? Da C für "int" mindestens 16 Bits vorschreibt... Was es definitiv gibt: Compiler, die die berüchtigte Regel, dass alle Rechnungen vom Ergebnis her mindestens in "int" durchzuführen seien, nur optional beherzigen. Das ist bei allen Architekturen mit ausschliesslich einem 8-Bit Akkumulator auch naheliegend, wenngleich nicht konform zum Standard.
Albert ... schrieb: > Dein Freund meint wahrscheinlich das ein integer 16 bit groß ist. Das > war nämlich wirklich historisch so das die größe eines Int mit der > breite des Datenbusses skaliert war. Der bruch kam dann erst bei > Einführung der 64bit Systeme. Das war schon vor 30 Jahren anno 68000 nicht mehr so eindeutig. Denn da gab es für den exakt gleichen Prozessor sowohl C-Compiler mit 16-Bit int als auch welche mit 32-Bit int. Warum 16 Bits: schneller, weil 16-Bit ALU und Datenbus. Warum 32 Bits: Adressbreite, damit Portabilität von Code, der diese Identität voraussetzt. Gabs damals anno K&R-C ohne Prototypes oft.
A. K. schrieb: > > Warum 32 Bits: Adressbreite, damit Portabilität von Code, der diese > Identität voraussetzt. Gabs damals anno K&R-C ohne Prototypes oft. Also für Portabilität gibt es Datentypen wie int32_t, die exakt 32 Bit groß sind. Das es Compiler gibt die ANSI-C nicht kennen und folglich auch int32_t nicht haben ist eine andere Geschichte, insbesondere bei Firmen wie IAR und Keil, aber wenn ich von C schreibe, dann meine ich ANSI-C und der einzige derzeit gültige Standard dafür ist C-99, weil jeder neue Standard die vorherigen für ungültig erklärt, allein schon um Mehrdeutigkeit auszuschließen. Übrigens habe ich einen anderen internationalen Standard gefunden, der ein Byte genau beschreibt: In IEC 60027-2 ist ein Byte ein Oktet von Bits, enthält also genau 8 Bit.
A. K. schrieb: > Erwin Meyer schrieb: > >> Also selbst wenn es sowas gibt, ist die Antwort meine Frage auch hier >> klar: Bei mehr als 9 Bit zeigen sich Bits auch an einer anderen Adresse > > Eben nicht. Die zweite Hälfte des Datenadressraums kennt keine Adressen > von 8-Bit Objekten, sondern nur Adressen von 16-Bit Objekten. Die Frage war nicht abhäng vom Adressraum, so das ein Test aller Adressen auf der erwähnten Plattform ergibt das das kleinste Objekt 8 Bit enthält.
Erwin Meyer schrieb: > Also für Portabilität gibt es Datentypen wie int32_t, die exakt 32 Bit > groß sind. Die erwähnte Portabilität bezog sich auf die Identität der Grösse von Pointern und "int", nicht auf "int" und 32 Bits. Auch das lässt sich machen, aber darum ging es nicht. Mir ist bekannt, dass dieses Thema heute keines mehr ist, aber die Story bezog sich ausdrücklich auf 68000 Anfang der 80er als es weder den vordefinierten Typ int32_t noch ANSI-C noch Parameterdeklarationen ausserhalb der Funktionsdefinition gab. Damals war das relevant. Das war überdies nur eine Replik auf Alberts These, dass sich erst bei 64-Bit Architekturen eine Schere zwischen Datenbusbreite und int ergeben hätte. Nope, das gab es schon viel früher.
Ein Byte hat die Größe 8 Bit erhalten, da sich dadurch mit 7 Bit ASCII darstellen ließe + 1 Parity-Bit. Deswegen sind es 8 Bit.
Erwin Meyer schrieb: > und Keil, aber wenn ich von C schreibe, dann meine ich ANSI-C und der > einzige derzeit gültige Standard dafür ist C-99, weil jeder neue > Standard die vorherigen für ungültig erklärt, allein schon um > Mehrdeutigkeit auszuschließen. M.a.W: Mindestens die meisten real existierenden C Compiler sind keine C Compiler, sondern Hochstapler und dürften sich folglich nicht so nennen, GCC eingeschlossen? Mal andersrum gefragt: Gibt es dieser Definition gemäss überhaupt einen C Compiler, der sich so nennen darf, weil er deinem Anspruch vollständiger Konformität zu C99 gerecht wird? Apropos: Ich weiss grad nicht, ob C99 wirklich alte Versionen von C für ungültig erklärt, aber etliche andere mir bekannte Standards sind versioniert, d.h. die Mehrdeutigkeit wird dadurch ausgeschlossen, dass die Version des Standards genannt wird. Würden neue Standards alte stets für ungültig erklären, dann müsste mit Verabschiedung eines neuen Standards die komplette bezügliche Industrie schlagartig solange den Betrieb einstellen, bis neue Produkte auf dem Markt sind, weil die bisherige Bezeichnung nur noch für die neuen Produkte zulässig sei. Grotesk.
Rufus Τ. Firefly schrieb: > Kennt jemand irgendeine real existierende C-Implementierung, bei der die > Größe eines int kleiner ist als 16 Bit? Mit avr-gcc -mint8 ist sizeof(int) = 1, allerdings wird diese Option nicht mehr gepflegt und ist in neueren Versionen spätestens ab 4.6 nicht mehr funktional. Um das "live" zu sehen, braucht mal also eine was angestaubte Version von avr-gcc.
Erwin Meyer schrieb: > Ein Bekannter meint weil er einen 16-Bit-Mikrocontroller verwendet und > daran einen 16-Bit-Datenbus hat sind bei ihm die Bytes alle 16 Bit groß. Wiki sagt dazu: Das Byte [baɪt] ist ein Mengenbegriff (Maßeinheit) in der Digitaltechnik und der Informatik, der für eine Zusammenstellung aus mehreren Bit steht, im Allgemeinen für eine Anzahl von 8. Das hat nichts mit einem Prozessor oder einem Compiler zu tun, sondern nur mit binärer Mathematik. Obwohl da steht "im Allgemeinen für eine Anzahl von 8", hab ich noch nie etwas anderes gesehen. Um binär zu rechnen, brauche ich keinen Computer, da tuns auch Papier und Bleistift. Dein Bekanter sollte auf einen 8-Bit-Mikrocontroller umsteigen, ansonsten ist für ihn ein 1KB Ram nur 512 Bytes groß ;-) MfG Klaus
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.