まず、ビッグエンディアン ストレージとは、個々のデータがメモリに保存されるモードを指します。
目次
ビッグエンディアンとスモールエンディアンを理解する
ビッグエンディアン (モード) ストレージ: データがメモリに格納されるときを指し、データの下位バイトはメモリの上位アドレスに格納され、データの上位バイトはメモリのアドレスに格納されます。メモリの下位アドレス。
リトル エンディアン (モード) ストレージ: ビッグ エンディアンの逆で、データの下位バイトはメモリの下位アドレスに格納され、データの上位バイトはメモリの上位アドレスに格納されます。
コード例
#include<stdio.h>
int main()
{
int a = 10;//存储一个整型,占4个字节
//00000000 00000000 00000000 00001010 ——10的二进制
//整数以二进制补码存储在内存中,但为了便于观察,故用十六进制代替
//四个二进制可以转换成一个十六进制
//0x 0000 0000 0000 000a ——10的十六进制(前面的0x表示十六进制)
// 高字节——————>低字节
return 0;
}
VS2022 を使用してデバッグし、メモリ ストレージを見てみましょう。
コンパイルされたデータから、整数 a は 4 バイトを占め、16 進形式でメモリに格納されていることがわかります。ストレージ モードは、メモリの下位アドレスに格納される下位バイト データと、メモリの下位アドレスに格納される上位バイト データに基づいています。メモリの上位アドレスに保存されているデータ。
もう 1 つ追加点: a は整数で、4 バイトを占有し、1 バイト (メモリ単位) は 1 アドレスを占有し、&a が取り出すのはメモリ内の下位アドレスです。
なぜ大きな端と小さな端があるのですか?
コンピュータシステムではアドレスの単位をバイト(8ビット)といいますが、コンピュータにはchar型が1つだけではなく、1バイトを超える型(short int long..)も存在します。例えば、16ビットや32ビットのプロセッサではレジスタの幅が1バイトよりも大きいため、複数のバイトをどのように配置するかという問題が発生するはずです。これは、ビッグ エンディアンとスモール エンディアンのストレージ モデルにつながります。
例:16ビットショート型 ビッグエンディアン モードの場合、0x11 が下位メモリ アドレス (0x0010) に配置される場合、0x22 は上位メモリ アドレス (0x0011) に配置される必要があります。リトルエンディアンモードは偶然にもその逆です。私たちが一般的に使用する x86 はリトル エンディアン モードですが、KIEL C51 はビッグ エンディアン モードです。多くの ARP DSP はリトルエンディアン モードです。一部の ARM プロセッサでは、ハードウェアによってビッグ エンディアン モードまたはリトル エンディアン モードを選択することもできます。ここまで述べたので、一言だけ言っておきます。ビッグエンディアンとスモールエンディアンはハードウェアに依存します。
コンパイラを解釈するコードを設計します。
アイデア: まず、ビッグ エンディアンとスモール エンディアンを決定したいので、ビッグ エンディアンとスモール エンディアンの違いを理解する必要があります。: メモリ内の単一データの格納順序 (これをブレークスルーとして使用できます)
実際の操作:
#include<stdio.h>
int main()
{
int a = 1;
//00 00 00 01 -———十六进制
char* p = (char*)&a;//强制类型转换&a为char*类型以便拿到低地址字节
//如果是大端:拿低位地址就是a的高字节数据0
//如果是小端:拿低位地址就是a的低字节数据1
if (*p == 1)
printf("小端");
else
printf("大端");
return 0;
}
簡略化する:
#include<stdio.h>
int Check(int x)
{
return *(char*)&x;//强制类型转换为char*,返回低地址数据
}
int main()
{
int a = 1;
if (Check(a) == 1)
printf("小端");
else
printf("大端");
return 0;
}
実際、単純化は 1 つだけです: char* p=(char*)&a; *p=*(char*)&a;