Wie kann Microsoft sagen, dass die Größe eines Wortes in WinAPI 16 Bits ist?

8

Ich habe gerade mit dem WinAPI angefangen. In der MSDN wird die folgende Erläuterung für den Datentyp WORD bereitgestellt.

  

WORT
  Eine 16-Bit-Ganzzahl ohne Vorzeichen. Der Bereich ist 0 bis 65535 dezimal.
  Dieser Typ wird in WinDef.h wie folgt deklariert:
  typedef unsigned short WORD;

Einfach genug, und es passt zu den anderen Ressourcen, die ich zum Lernen verwendet habe, aber wie kann es definitiv gesagt werden, dass es 16 Bits sind? Die C-Dateitypen Seite in Wikipedia gibt

an
  

kurz / kurz int / signiert kurz / signiert kurz int   Kurze vorzeichenbehaftete Ganzzahl   Art. Kann mindestens den Bereich [-32767, +32767] enthalten; so,   es ist mindestens 16 Bits groß.

Die Größe eines short könnte also nach dem C-Standard sehr gut 32 Bit betragen. Aber wer entscheidet, welche Bitgrößen sowieso verwendet werden? Ich fand eine praktische Erklärung hier. Insbesondere die Zeile:

  

... es hängt von beiden Prozessoren ab (genauer ISA, Anweisung)   Architektur, z. B. x86 und x86-64) und Compiler einschließlich   Programmiermodell.

Also ist es die ISA, die einen Sinn ergibt, nehme ich an. Hier bin ich verloren. Werfen wir einen Blick auf die Windows-Seite auf Wikipedia, die ich in der Seitenleiste sehe:

  

Plattformen   ARM, IA-32, Itanium, x86-64, DEC-Alpha, MIPS, PowerPC

Ich weiß nicht wirklich, was das ist, aber ich denke, das sind Prozessoren, von denen jeder eine ISA haben würde. Vielleicht unterstützt Windows diese Plattformen, weil sie garantiert 16 Bits pro unsigned short verwenden? Das hört sich nicht ganz richtig an, aber ich weiß nicht genug über dieses Zeug, um weiter zu recherchieren.

Zurück zu meiner Frage: Wie kann es sein, dass die Windows-API typedef unsigned short WORD; und dann WORD eine vorzeichenlose 16-Bit-Ganzzahl ist, wenn der C-Standard selbst nicht garantiert, dass ein short immer 16 Bits ist?

    
brokyle 18.05.2016, 19:23
quelle

6 Antworten

9

Einfach gesagt, ein WORD ist immer 16 Bits.

Ein WORD ist immer 16 Bits, aber ein unsigned short ist nicht, ein WORD ist nicht immer ein unsigned short .

Für jede Plattform, die vom Windows SDK unterstützt wird, enthält die Windows-Headerdatei #ifdef style-Makros, die den Compiler und seine Plattform erkennen und die vom Windows SDK definierten Typen ( WORD , DWORD usw.) zuordnen können die entsprechend großen Plattformtypen.

Dies ist der Grund, warum das Windows SDK tatsächlich intern definierte Typen wie WORD anstelle von Sprachtypen verwendet, damit sie sicherstellen können, dass ihre Definitionen immer korrekt sind.

Das Windows SDK, das mit Microsoft Toolchains ausgeliefert wird, ist möglicherweise faul, da Microsoft C ++ - Toolchains immer unsignierte 16-Bit-Kurzschlüsse verwenden.

Ich würde nicht erwarten, dass die windows.h, die mit Visual Studio C ++ ausgeliefert wird, korrekt funktioniert, wenn sie in GCC, clang usw. fallen, da so viele Details, einschließlich des Mechanismus zum Importieren von DLLs mit .iib-Dateien, die das Platform SDK verteilen eine Microsoft-spezifische Implementierung.

Eine andere Interpretation ist das:

Microsoft sagt ein WORD ist 16 Bits. Wenn "jemand" eine Windows-API aufrufen möchte, muss ein 16-Bit-Wert übergeben werden, wobei die API das Feld als WORD definiert. Microsoft möglicherweise auch sagt, um ein gültiges Windows-Programm zu erstellen, mit den Windows-Header-Dateien in ihrem Windows SDK vorhanden, muss der Benutzer einen Compiler wählen, der eine 16bit short hat.

Die C ++ - Spezifikation sagt nicht, dass Compiler short s als 16 Bits implementieren müssen - Microsoft sagt, dass der Compiler, den Sie zum Erstellen von Windows-Executables auswählen, muss.

    
Chris Becke 18.05.2016 19:36
quelle
7

Ursprünglich wurde angenommen, dass der gesamte Code, der unter Windows ausgeführt werden soll, mit dem eigenen Compiler von Microsoft kompiliert werden würde - oder mit einem vollständig kompatiblen Compiler. Und so hat es funktioniert. Borland C: Matched Microsoft C. Zortechs C: Matched Microsoft C. gcc: nicht so sehr, also hast du es nicht einmal versucht (ganz zu schweigen davon, dass es keine Laufzeiten gab, etc.).

Im Laufe der Zeit wurde dieses Konzept kodifiziert und auf andere Betriebssysteme erweitert (oder vielleicht haben die anderen Betriebssysteme es zuerst bekommen) und jetzt ist es bekannt als ein ABI - Binäre Anwendungsschnittstelle - für eine Plattform und alle Compiler für diese Plattform werden (in der Praxis vorausgesetzt) ​​als ABI-konform angenommen. Und das bedeutet unter anderem, die Erwartungen an die Größen der integralen Typen anzupassen.

Eine interessante verwandte Frage, die Sie nicht gestellt haben, ist: Warum werden 16-Bit ein Wort genannt? Warum ist 32-Bit ein dword (Doppelwort) auf unseren 32- und jetzt 64-Bit-Architekturen, wo die native Maschine "Wort" -Größe 32- oder 64- ist, nicht 16? Weil: 80286.

    
davidbak 18.05.2016 19:33
quelle
2

In den Windows-Headern gibt es eine Menge #define, die basierend auf der Plattform sicherstellen können, dass ein WORD 16 Bit, ein DWORD 32 usw. ist. In einigen Fällen weiß ich, dass sie ein richtiges SDK für jede Plattform verteilen . Auf jeden Fall nichts magisches, nur eine Mischung aus richtigen #defines und headern.

    
Felice Pollano 18.05.2016 19:28
quelle
1

Die Terminologie BYTE=8bits , WORD=16bits und DWORD=32bits (Doppelwort) stammt aus Intels Instruktions-Mnemonics und Dokumentation für 8086. Es ist nur eine Terminologie und impliziert zu diesem Zeitpunkt nichts über die Größe des" Maschinenworts " auf der tatsächlichen Maschine, auf der der Code ausgeführt wird.

Meine Vermutung:

Diese C-Typnamen wurden wahrscheinlich ursprünglich aus demselben Grund eingeführt wie C99 standardisiert uint8_t , uint16_t und uint32_t . Die Idee war wahrscheinlich, C-Implementierungen mit einem inkompatiblen ABI (zB 16bit int oder 32bit short ) weiterhin Code zu kompilieren, der die WinAPI verwendet, weil die ABI DWORD anstatt long oder int verwendet struct s und Funktion args / return values.

Wahrscheinlich ist Windows so weit entwickelt, dass genug Code auf verschiedene Arten auf die genaue Definition von WORD und DWORD angewiesen ist, die MS zu standardisieren Sie die genaue typedef s . Dies unterscheidet sich von der C99 uint16_t Idee, bei der Sie nicht davon ausgehen können, dass es unsigned short ist.

Als @supercat weist darauf hin , das kann für Aliasing-Regeln von Bedeutung sein. z.B. Wenn Sie ein Array von unsigned long[] bis DWORD* ändern, ist garantiert, dass es wie erwartet funktioniert. Wenn Sie jedoch ein Array von unsigned int[] durch DWORD* ändern, könnte der Compiler davon ausgehen, dass Array-Werte, die er bereits in Registern hatte, nicht betroffen waren. Dies gilt auch für printf Formatzeichenfolgen. (C99's <stdint.h> Lösung dazu ist Präprozessormakros wie PRIu32 .)

Oder vielleicht bestand die Idee nur darin, Namen zu verwenden, die mit dem asm übereinstimmen, um sicherzustellen, dass niemand über die Breite der Typen verwirrt ist. In den frühen Tagen von Windows war das Schreiben von Programmen in Asm direkt statt C populär. WORD / DWORD macht die Dokumentation für Personen, die in asm schreiben, klarer.

Oder vielleicht bestand die Idee nur darin, einen Typ mit fester Breite für portablen Code bereitzustellen . z.B. #ifdef SUNOS : Definieren Sie einen passenden Typ für diese Plattform. Das ist alles, was zu diesem Zeitpunkt gut ist, wie Sie bemerkt haben:

  

Wie kann es sein, dass die Windows-API typedef unsigned short WORD eingeben kann? und dann sagen WORD ist eine 16-Bit-Ganzzahl ohne Vorzeichen, wenn der C-Standard selbst nicht garantiert, dass ein Kurzschluss immer 16 Bits ist?

Sie haben Recht, wenn Sie das genaue typedef s dokumentieren, ist es unmöglich, die WinAPI-Header in einem System mit einem anderen ABI korrekt zu implementieren (z. B. mit long ist 64bit oder short ist 32bit). Dies ist einer der Gründe, warum der x86-64 Windows ABI long zu einem 32bit Typ macht. Das x86-64-System V ABI (Linux, OS X usw.) macht long zu einem 64-Bit-Typ.

Jede Plattform benötigt jedoch einen Standard-ABI, . struct layout und sogar die Interpretation von Funktionsargumenten erfordert, dass der gesamte Code der Größe der verwendeten Typen entspricht. Code aus verschiedenen Versionen desselben C-Compilers kann zusammenarbeiten und sogar andere Compiler, die demselben ABI folgen. (C ++ - ABIs sind jedoch nicht stabil genug, um zu standardisieren. Zum Beispiel hat g++ niemals einen ABI standardisiert, und neue Versionen brechen die ABI-Kompatibilität.)

Denken Sie daran, dass der C-Standard Ihnen nur sagt, was Sie bei jeder konformen C-Implementierung erwarten können. Der C-Standard besagt auch, dass vorzeichenbehaftete Ganzzahlen Zeichen / Betrag, Einerkomplement oder Zweierkomplement sein können. Jede spezifische Plattform verwendet jedoch jede Darstellung der Hardware.

Plattformen können alles standardisieren, was der Basis-C-Standard nicht definiert oder implementierungsdefiniert lässt. z.B. x86 C-Implementierungen ermöglichen das Erstellen von nicht ausgerichteten Zeigern und sogar deren Dereferenzierung. Dies geschieht sehr häufig mit __m128i vector types.

Die gewählten Namen binden die WinAPI an ihr x86-Erbe und sind leider verwirrend für alle, die sich nicht mit x86 asm oder zumindest mit dem 16-Bit-DOS-Erbe von Windows auskennen.

Die 8086-Befehls-Mnemotechniken, die w für Word und d für dword enthalten, wurden häufig als Setup für % co_de verwendet % signierte Division .

  • idiv : Zeichen verlängern AL (Byte) in AX (Wort)
  • cbw : zeichen erweitern AX (Wort) in DX: AX (dword) , dh kopieren das Vorzeichen-Bit von cwd in jedes Bit von ax .

Diese Insnts existieren immer noch und machen genau dasselbe im 32-Bit- und 64-Bit-Modus.

Peter Cordes 19.05.2016 12:20
quelle
0

Derzeit gibt es keine Plattformen, die Windows API unterstützen, aber unsigned short als nicht 16-bit.

Wenn jemand jemals eine solche Plattform erstellt hat, enthalten die Windows-API-Header für diese Plattform nicht die Zeile typedef unsigned short WORD; .

Sie können sich MSDN-Seiten als typisches Verhalten von MSVC ++ auf x86 / x64-Plattformen vorstellen.

    
M.M 18.05.2016 20:49
quelle
0

Das Legacy für Typen wie WORD ist älter als Windows, zurück zu den Tagen von MSDOS nach den Typen, die von MASM definiert wurden (später wurde der Name in ML geändert). Von der Windows-API nicht übernommen sind MASMs signierte Typen wie SBYTE, SWORD, SDWORD, SQWORD.

QWORD / SQWORD in MASM wurde wahrscheinlich nicht definiert, bis MASM / ML 80386 unterstützt.

Eine aktuelle Referenz:

Ссылка

Windows hat Typen wie HANDLE, WCHAR, TCHAR, ... hinzugefügt.

Bei Windows / Microsoft-Compilern ist size_t eine vorzeichenlose Ganzzahl mit der gleichen Größe wie ein Poitner, 32 Bit im 32-Bit-Modus, 64 Bit im 64-Bit-Modus.

Die DB- und DW-Datenanweisungen in MASM gehen auf die Tage von Intels 8080-Assembler zurück.

    
rcgldr 19.05.2016 01:46
quelle

Tags und Links