あなたは非常に興味深く、トリッキーな質問をしています。
要するに、競合する型ファミリの存在につながる 2 つの要因がありました。DWORD ベースと int ベースです。
1) 一方ではクロスプラットフォーム性を持ち、他方では厳格なサイズ タイプを持ちたいと考えています。
2) 人々の保守主義。
いずれにせよ、あなたの質問に完全に詳細な回答を提供し、この分野の十分な背景を提供するには、コンピューターの歴史を掘り下げる必要があります。そして、コンピューティングの黎明期から話を始めましょう。
まず、機械語のような概念があります。マシン ワードは、特定のプロセッサでの処理に適した厳密なサイズのバイナリ データのチャンクです。そのため、マシン ワードのサイズはほとんどプロセッサに依存せず、一般に一般的な内部プロセッサ レジスタのサイズと同じです。通常、データの独立したチャンクとしてプロセッサからアクセスできる 2 つの等しい部分に分割できます。たとえば、x86 プロセッサでは、マシン ワードのサイズは 32 ビットです。これは、すべての汎用レジスタ (eax、ebx、ecx、edx、esi、edi、ebp、esp、および eip) が同じサイズ (32 ビット) であることを意味します。しかし、それらの多くはレジスターの一部としてアクセスできます。たとえば、eax は 32 ビット データ チャンク、ax は 16 ビット データ チャンク、al は 8 ビット データ チャンクとしてアクセスできます。しかし、物理的にこれがすべて 1 つの 32 ビット レジスタであるとは限りません。ウィキペディア (http://en.wikipedia.org/wiki/Word_(computer_architecture)) で、その分野に関する非常に優れた背景を見つけることができると思います。要するに、マシンワードは、単一の命令の整数オペランドとして使用できるビットデータチャンクの量です。今日でも、プロセッサ アーキテクチャが異なれば、マシン語のサイズも異なります。
わかりました、コンピューターワードについてある程度理解しました。今こそ、コンピューティングの歴史に立ち返る時です。普及した最初の Intel x86 プロセッサのワード サイズは 16 ビットでした。1978 年に市場に登場しました。当時、アセンブラは主要なプログラミング言語ではないにしても非常に人気がありました。ご存じのように、アセンブラーは、ネイティブ プロセッサ言語の非常に薄いラッパーにすぎません。このため、完全にハードウェアに依存します。Intel が新しい 8086 プロセッサを市場に投入するとき、成功を収めるために最初に必要だったのは、新しいプロセッサのアセンプラも市場に投入することでした。誰もプログラミングの方法を知らないプロセッサを望んでいる人はいません。Intel が 8086 のアセンブラでさまざまなデータ型に名前を付けたとき、彼らは明らかな chois を作成し、16 ビット データ チャンクを単語として命名しました。8086 の機械語は 16 ビット サイズであるためです。機械語の半分をバイト (8 ビット) と呼び、1 つのオペランドとして使用される 2 語をダブルワード (32 ビット) と呼びました。Intel は、プロセッサのマニュアルとアセンブラのニーモニック (バイト、ワード、およびダブルワードの静的割り当てを表す db、dw および dd) でこの用語を使用しました。
年月が経ち、1985 年に Intel は 16 ビット アーキテクチャから 32 ビット アーキテクチャに移行し、80386 プロセッサが導入されました。しかし当時は、16 ビット値という言葉に慣れていた開発者が非常に多かったのです。それに加えて、単語が 16 ビットであるという真の信念を持って書かれた膨大な量のソフトがありました。そして、すでに書かれたコードの多くは、ワードが 16 ビットであるという事実に依存しています。このため、マシン語のサイズが実際に変更されたという事実に加えて、新しいデータ型がアセンブラに到着したという事実を除いて、表記法は同じままでした - クアッドワード (64 ビット)。単語は同じままでしたが、機械語が拡張されました。同様に、ダブル クワッド ワード (128 ビット) が 64 ビット AMD64 アーキテクチャで登場しました。その結果、
byte = 8 bit
word = 16 bit
dword = 32 bit
qword = 64 bit
dqword = 128 bit
その型ファミリーの主な点は、それが強力なサイズの型ファミリーであることに注意してください。それはアセンブラーで頻繁に使用されているため、一定サイズのデータ型が必要です。年は 1 年ずつ過ぎていきますが、このファミリのデータ型は、その名前が元の意味をすでに持っていないという事実に加えて、同じ一定のサイズを持ち続けていることに注意してください。
一方、同じ時期に、高級言語は年々人気が高まってきました。そして、その言語はクロスプラットフォーム アプリケーションを念頭に置いて開発されたため、まったく別の観点から内部データ型のサイズに注目しました。私が正しく理解していれば、内部データ型の一部が将来変更されることのない固定の定数サイズを持っていると明確に主張している高級言語はありません。例のように C++ を見ないでください。C++ 標準では、次のように説明されています。
"The fundamental storage unit in the C++ memory model is the byte. A byte is at
least large enough to contain any member of the basic execution character set and
is composed of a contiguous sequence of bits, the number of which is implementa-
tion-defined. The least significant bit is called the low-order bit; the most
significant bit is called the high-order bit. The memory available to a C++ program
consists of one or more sequences of contiguous bytes. Every byte has a unique
address."
したがって、驚くべき情報を見ることができます。C++ では、バイトでさえ一定のサイズではありません。したがって、サイズが8ビットであると考えることに慣れていても、C ++によれば、サイズは8ビットだけでなく、9、10、11、12などのビットにもなる可能性があります。そして多分7ビット。
"There are five signed integer types: “signed char”, “short int”, “int”, and
“long int”., and “long long int”. In this list, each type provides at least as
much storage as those preceding it in the list. Plain ints have the natural size
suggested by the architecture of the execution environment; the other signed
integer types are provided to meet special needs."
その引用は、2 つの主要な主張を説明しています。
1) sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
2) プレーン int は、実行環境のアーキテクチャによって提案される自然なサイズを持ちます。つまり、int はターゲット プロセッサ アーキテクチャのマシン ワード サイズでなければなりません。
すべての C++ 標準テキストを調べることができますが、「int のサイズは 4 バイト」または「long の長さは 64 ビット」のようなものは見つかりません。特定の整数 C++ 型のサイズは、あるプロセッサ アーキテクチャから別のプロセッサ アーキテクチャに移動したり、あるコンパイラから別のコンパイラに移動したりすると変化する可能性があります。しかし、C++ でプログラムを作成する場合でも、既知の定数サイズのデータ型を使用する必要に定期的に直面します。
少なくとも以前のコンパイラ開発者は、その標準的な主張に従いました。しかし今、人々の保守主義が再び登場することがわかります。int は 32 ビットであり、–2,147,483,648 から 2,147,483,647 の範囲の値を格納できると考えられていました。業界が 16 ビット アーキテクチャと 32 ビット アーキテクチャの境界を通過した以前のことです。2 番目の主張は厳密に実施されました。また、C++ コンパイラを使用して 16 ビット プログラムを作成すると、コンパイラは 16 ビット プロセッサの「自然なサイズ」である 16 ビット サイズの int を使用し、対照的に、別の C++ コンパイラを使用して 32 ビット プログラムを作成すると、同じソース コードから、コンパイラは 32 ビット プロセッサの「自然なサイズ」である 32 ビット サイズの int を使用しました。今日、たとえば、
要約すると、dword ベースと int ベースの 2 つのデータ型ファミリがあることがわかります。2 つ目の理由は明らかです。クロスプラットフォーム アプリケーションの開発です。最初のものの動機は、変数のサイズを考慮に入れることが理にかなっている場合です。たとえば、次のケースを挙げることができます。
1) 事前に定義された既知の範囲に何らかの値が必要であり、それをクラスまたは実行時に膨大な数のインスタンスに入力される別のデータ構造で使用する必要があります。その場合、int ベースの型を使用してその値を格納すると、一部のアーキテクチャではメモリのオーバーヘッドが大きくなるという欠点があり、別のアーキテクチャではロジックが壊れる可能性があります。たとえば、0 から 1000000 の範囲の値を操作する必要があります。int を使用して格納する場合、int が 32 ビットの場合、プログラムは正しく動作し、int の場合、各値インスタンスごとに 4 バイトのメモリ オーバーヘッドが発生します。 int が 16 ビットの場合、64 ビットになり、正しく動作しません。
2)次の作業に関わるデータ。さまざまな PC でネットワーク プロトコルを正しく処理できるようにするには、すべてのパケットとヘッダーをビットごとに記述するサイズベースの形式でプレーンに指定する必要があります。ある PC ではプロトコル ヘッダーが 32 ビットで長さが 20 バイトになり、別の PC では 64 ビット int で長さが 28 バイトになると、ネットワーク通信は完全に切断されます。
3) プログラムは、いくつかの特別なプロセッサ命令に使用される値を格納する必要があります。そうしないと、プログラムはアセンブラで記述されたモジュールまたはコード チャンクと通信します。
4) デバイスとの通信に使用されるストア値が必要です。各デバイスには、入力として必要な入力デバイスの種類と、出力を提供する形式を記述する独自の仕様があります。デバイスが入力として 16 ビット値を必要とする場合、int サイズに関係なく、デバイスがインストールされているシステムのプロセッサで使用されるマシン ワード サイズに関係なく、16 ビット値を等しく受け取る必要があります。
5) アルゴリズムは整数オーバーフロー ロジックに依存しています。たとえば、2 ^ 16 エントリの配列があり、それを無限に連続して通過し、エントリの値を更新したいとします。16 ビット int を使用する場合、プログラムは完全に動作しますが、すぐに 32 ビット int の使用に移行すると、範囲外の配列インデックス アクセスが発生します。
このため、Microsoft では両方のファミリのデータ型を使用しています。実際のデータ サイズがそれほど重要でない場合は Int ベースの型、重要な場合は DWORD ベースの型。その場合でも、Microsoft は両方をマクロとして定義し、Microsoft が使用する仮想型システムを特定のプロセッサ アーキテクチャやコンパイラに適切な C++ 相当物を割り当てることで、迅速かつ簡単に採用できるようにします。
データ型の起源とその違いに関する質問を十分にカバーできたことを願っています。
したがって、DWORD ベースのデータ型の値を示すために 16 進数が使用される理由に関する 2 番目の質問に切り替えることができます。実際にはいくつかの理由があります。
1) 厳密なサイズのバイナリ データ型を使用する場合、バイナリ形式で見たいと思うほど十分に期待できます。
2) バイナリ形式でエンコードされたビット マスク値を理解するのは非常に簡単です。次の形式の値の場合、どのビットが設定され、どのビットがリセットされるかを理解するのがはるかに簡単であることに同意します
1100010001011001
次に、次の形式でエンコードされる場合
50265
3) バイナリ形式でエンコードされ、1 つの DWORD ベースの値で記述されたデータは、10 進数形式でエンコードされた同じデータが可変長になる場合、一定の長さになります。小さい数値がバイナリ形式でエンコードされている場合でも、完全な値の説明が提供されることに注意してください。
0x00000100
それ以外の
0x100
バイナリ エンコーディングのこの特性は、膨大な量のバイナリ データの分析が必要な場合に非常に魅力的です。たとえば、16 進エディターや、ブレークポイントにヒットしたときにデバッガーでプログラムが使用するプレーン メモリの分析などです。整列が不十分な変数サイズの値のヒープよりも、きちんとした値の列を確認する方がはるかに快適であることに同意してください。
そこで、バイナリ エンコーディングを使用することにしました。プレーン バイナリ エンコーディングを使用する、8 進エンコーディングを使用する、16 進エンコーディングを使用するという 3 つの選択肢があります。16 進エンコーディングは、使用可能なエンコーディングのセットの中で最も短いため、人々は 16 進エンコーディングを使用することを好みます。比較するだけ
10010001101000101011001111000
と
0x1234568
次の値に設定されているビット数をすぐに見つけることができますか?
00000000100000000000000000000
そして次は?
0x00100000
2 番目のケースでは、数値を 4 バイトですばやく分割できます。
0x00 0x10 0x00 0x00
3 2 1 0
それぞれの最初の桁は 4 つの最上位ビットを表し、2 番目の桁は別の 4 つの最下位ビットを表します。16 進数値の操作に時間を費やした後、各 16 進数の単純なビット アナログを覚えて、問題なく頭の中で 1 つずつ置き換えることができます。
0 - 0000 4 - 0100 8 - 1000 C - 1100
1 - 0001 5 - 0101 9 - 1001 D - 1101
2 - 0010 6 - 0110 A - 1010 E - 1110
3 - 0011 7 - 0111 B - 1011 F - 1111
したがって、ビット番号 20 が設定されていることを確認するのに 1 ~ 2 秒しかかかりません。
人々が 16 進数を使用するのは、16 進数が最も短く、理解しやすく、バイナリ データ エンコーディングの形式を使用するのに適しているためです。