Ich habe die vorverarbeitete Ausgabe meines C-Programms überprüft und zufällig einen Blick auf die Header-Datei geworfenwordsize.h
Es liegt in
/usr/include/i386-linux-gnu/bits/wordsize.h
die Datei enthält nur ein Makro
#define __WORDSIZE 32
Meine Frage ist nun, ob die Wortgröße dann durch den installierten Compiler bestimmt wird oder ob es etwas mit dem von mir installierten Betriebssystem (32 Bit oder 64 Bit) oder mit der Hardwarekonfiguration meines Computers zu tun hat.
Ich bin neu in der Entwicklung unter Linux.
Antwort1
Allgemeinwordsize
wird beim Kompilieren anhand der Zielarchitektur entschieden. Ihr Compiler kompiliert normalerweise wordsize
mit dem aktuellen System.
Mit gcc
(unter anderem) können Sie dies auch durch die Verwendung verschiedener Flags optimieren. Auf einem 64-Bit-Host können Sie beispielsweise kompilieren für32 BitMaschine oderGewalt32-Bit-Wörter.
-m32 # int, long and pointer to 32 bits, generates code for i386.
-m64 # int, long and pointer to 64 bits, generates code for x86-64.
-mx32 # int, long and pointer to 32 bits, generates code for x86-64.
Sie sollten sich auch limits.h
die inttypes.h
Verwendung dieser Definition ansehen.
Informationen zum Cross-Compiling finden Sie unterMultilib(32-Bit-Link auf SO) und durchsuchen Sie das Internet.
Überprüfen Sie, mit welchen Flags Ihr GCC erstellt wurde:
gcc -v
Die Größen hängen normalerweise eng mit der zentralen Verarbeitungseinheit zusammen und sind verwandt – wie etwa die maximale Größe einer Speicheradresse, die Größe der CPU-Register usw.
Für einen schnellen Einblick müssen Sie nicht viel davon verstehen, aber je nachwo bist dues kann einen Einblick geben:
Wenn Sie gcc
das Flag verwenden und damit kompilieren, -S
können Sie sich auch dieMontageanleitungen. Das ist etwas verwirrend, denn auf einer 32-Bit-Maschine ist ein Wort beispielsweise 16 Bit und lang 32 Bit. ( __WORDSIZE
)
So zB movl $123, %eax
bedeutet move long (32-bit - __WORDSIZE
)123
Registriereneax
, und movw
bedeutet „Wort verschieben“ (16 Bit).
Dies sind Namenskonventionen, und nur zu sagen, dass das WORDSIZE
mehr als eine Sache bedeuten kann. Sie können auch auf Code stoßen, in dem beispielsweise etwas wie
#define WORD_SIZE 16
__WORDSIZE
da alles vom Kontext abhängt. Wenn Sie Daten aus einer Datei oder einem Stream lesen, deren Quelle eine Wortgröße von 16 Bit hat, wäre dies natürlich. Nur um darauf hinzuweisen, dass Sie beim Lesen im Code nicht immer von Wortgröße ausgehen sollten .
Ein Beispiel mit benutzerdefinierten Befehlen WORD_SIZE
würde den Befehlssatz im generierten Maschinencode nicht beeinflussen. Für GCC im Allgemeinen würde ich empfehlendieses Buch.(Leider ist es schon etwas älter – aber ich habe bisher kein ähnlich gut lesbares, aktuelleres Buch gefunden. (Nicht, dass ich besonders intensiv danach gesucht hätte.) Es ist kurz, prägnant und nett. Und wenn man nur bedenkt, dass sich Dinge geändert haben können, wie z. B. hinzugefügte Funktionen usw., ist es trotzdem eine gute Einführung.)
Es gibt eine schnelle und nette Einführung in die verschiedenen Aspekte beim Kompilieren. SieheKapitel 11für eine schöne Erklärung der Kompilierungskette.
Ich kenne keine Optionen in GCC, um 16-Bit zu kompilieren. Eine Möglichkeit wäre, in Assembler zu schreiben und anzugeben, dass .code16
der Code 16-Bit sein soll.
Beispiel:
.file "hello.s"
.text
.code16 /* Tel GAS to use 16-bit instructions. */
.globl start, _start
start:
_start:
movb $0x48, %al
...
Dies wird beispielsweise von Bootloadern wie GRUB und LILO für den MBR
auf Ihrer Festplatte vorhandenen Code benötigt.
Der Grund dafür ist, dass sich die CPU beim Hochfahren Ihres Computers in einem speziellen Modus befindet, in dem sie keine 32-Bit-, sondern maximal 16-Bit-Anweisungen hat. Real-Modus.
Kurz gesagt, das BIOS führt einen Hardwaretest durch, lädt dann die ersten 512 Bytes Ihrer Bootdiskette in den Speicher und überlässt die Kontrolle dem Code, der bei der Adresse beginnt 0
. Dieser Code wiederum findet heraus, wo sich die nächste Stufe der Dateien befindet, lädt diese in den Speicher und führt sie weiter aus, bis er schließlich eingibt
SicherheitsmodusWo du hastnormal32-Bit-Modus.
Antwort2
Hier ist, was meiner hat:
% cat /usr/include/bits/wordsize.h
/* Determine the wordsize from the preprocessor defines. */
#if defined __x86_64__
# define __WORDSIZE 64
# define __WORDSIZE_COMPAT32 1
#else
# define __WORDSIZE 32
#endif
Es wird also durch bestimmt wordsize.h
, das mit Ihrem Compiler geliefert wird. Aber ein intelligenter Compiler wird eine geeignete Größe auswählen.
Antwort3
Sie sollten die Standardwortgröße beim Kompilieren auswählen können, im Allgemeinen mithilfe einer der Optionen -m32
oder -m64
.
/usr/include/i386-linux-gnu/bits/wordsize.h
ist für die Kompilierung von 32-Bit-Anwendungen vorgesehen.
Es sollte /usr/include/x86_64-linux-gnu/bits/wordsize.h
eine 64-Bit- __WORDSIZE
Definition vorhanden sein.
Diese Änderung wurde mit Ubuntu 11.4 eingeführt:https://wiki.ubuntu.com/MultiarchSpec
Wenn -m64
dies fehlschlägt, verfügen Sie möglicherweise über eine 32-Bit-Distribution. uname -m
Ich werde es Ihnen sagen.
Obwohl es möglich ist, 64-Bit-Binärdateien auf einem 32-Bit-System zu plattformübergreifend zu kompilieren, wäre dies unpraktisch, da Sie sie dort nicht auf einfache Weise ausführen könnten.
Wenn Ihre CPU ein 64-Bit-Modell ist (prüfen Sie dies mit lscpu
), möchten Sie möglicherweise eine 64-Bit-Distribution installieren, um problemlos Multiarch-Pakete erstellen zu können.