little-endian 处理器如何在 C 的内存中保存一个数字?
How does little-endian processor save a number in their memory in C?
short a = 0x1234;
char *p = &a;
printf("%x%x", *p, *(p+1));
output
3412
我很好奇内存如何存储值 0x1234。我首先认为0x1234在内存中保存为0x3412(按字节反转),但根据lsb 0编号,内存将0x1234保存为0x2c48(按位反转)似乎是正确的我认为值0x1234在内存中保存为0x2c48并且little-endian cpu 将 0x2c48 视为 0x1234。这是正确的吗?
在小端系统上,多字节字以 byte 倒序存储。
例如16位字0x1234
将以0x34
存储在低地址,0x12
存储在高地址。
作为字节数组,它将是
uint8_t word[2] = { 0x34, 0x12 };
一个字节的位从不反转。
像 0x12345678
这样的 32 位(四字节)字将按 0x78
、0x56
、0x34
和 0x12
的顺序存储(从低地址到高地址)。
Little Endian 处理器首先存储最低有效字节,然后存储更高有效字节。
例如short int a = 0x1234
将存储为
|------|------|
| 0x34 | 0x12 |
|------|------|
一个 32 位整数 unsigned int b = 0x12345678
存储为
|------|------|------|------|
| 0x78 | 0x56 | 0x34 | 0x12 |
|------|------|------|------|
不可能找出您的 CPU 存储位的 "order",因为您无法寻址单个位。
Little-endian 表示 CPU 首先存储最低字节。但是 first 是什么意思呢?这意味着最低地址。位没有地址,因此无法判断哪个是第一个。故事结束。
以下是我们如何判断一个 CPU 是否为小端字节序:
LITTLE ENDIAN BIG ENDIAN
words: 0x1234 words: 0x1234
/---------------\ /---------------\
bytes: 0x34 0x12 bytes: 0x34 0x12
/------\ /------\ /------\ /------\
+------+ +------+ +------+ +------+
| 0x34 | | 0x12 | | 0x34 | | 0x12 |
+------+ +------+ +------+ +------+
Address: 5000 5001 Address: 5001 5000
我两边写的字节顺序一样,但是地址不一样
这就是您区分小端和大端的方式。您向地址 5000 写入一个字,然后检查地址为 5000 的字节是否包含 0x34 或 0x12。
现在,有了 bits,你会遇到这种情况:
LITTLE BIT-ENDIAN BIG BIT-ENDIAN
bytes: 0x34 words: 0x34
/---------------\ /---------------\
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
bits: |0|0|1|0|1|1|0|0| bits: |0|0|1|0|1|1|0|0|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
address: 5000 5000
我两边写的位顺序是一样的,但是地址是一样的。只有字节有地址。各个位没有地址。如果他们有地址,你可以要求,比方说,位 5000.4 并查看它是 1 还是 0 来确定位是小端还是大端,但它们没有,所以你不能。
如果您存储一个字节然后将其读回,您将获得相同的字节值,无论您的系统是小端还是大端位。
short a = 0x1234;
char *p = &a;
printf("%x%x", *p, *(p+1));
output
3412
我很好奇内存如何存储值 0x1234。我首先认为0x1234在内存中保存为0x3412(按字节反转),但根据lsb 0编号,内存将0x1234保存为0x2c48(按位反转)似乎是正确的我认为值0x1234在内存中保存为0x2c48并且little-endian cpu 将 0x2c48 视为 0x1234。这是正确的吗?
在小端系统上,多字节字以 byte 倒序存储。
例如16位字0x1234
将以0x34
存储在低地址,0x12
存储在高地址。
作为字节数组,它将是
uint8_t word[2] = { 0x34, 0x12 };
一个字节的位从不反转。
像 0x12345678
这样的 32 位(四字节)字将按 0x78
、0x56
、0x34
和 0x12
的顺序存储(从低地址到高地址)。
Little Endian 处理器首先存储最低有效字节,然后存储更高有效字节。
例如short int a = 0x1234
将存储为
|------|------|
| 0x34 | 0x12 |
|------|------|
一个 32 位整数 unsigned int b = 0x12345678
存储为
|------|------|------|------|
| 0x78 | 0x56 | 0x34 | 0x12 |
|------|------|------|------|
不可能找出您的 CPU 存储位的 "order",因为您无法寻址单个位。
Little-endian 表示 CPU 首先存储最低字节。但是 first 是什么意思呢?这意味着最低地址。位没有地址,因此无法判断哪个是第一个。故事结束。
以下是我们如何判断一个 CPU 是否为小端字节序:
LITTLE ENDIAN BIG ENDIAN
words: 0x1234 words: 0x1234
/---------------\ /---------------\
bytes: 0x34 0x12 bytes: 0x34 0x12
/------\ /------\ /------\ /------\
+------+ +------+ +------+ +------+
| 0x34 | | 0x12 | | 0x34 | | 0x12 |
+------+ +------+ +------+ +------+
Address: 5000 5001 Address: 5001 5000
我两边写的字节顺序一样,但是地址不一样
这就是您区分小端和大端的方式。您向地址 5000 写入一个字,然后检查地址为 5000 的字节是否包含 0x34 或 0x12。
现在,有了 bits,你会遇到这种情况:
LITTLE BIT-ENDIAN BIG BIT-ENDIAN
bytes: 0x34 words: 0x34
/---------------\ /---------------\
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
bits: |0|0|1|0|1|1|0|0| bits: |0|0|1|0|1|1|0|0|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
address: 5000 5000
我两边写的位顺序是一样的,但是地址是一样的。只有字节有地址。各个位没有地址。如果他们有地址,你可以要求,比方说,位 5000.4 并查看它是 1 还是 0 来确定位是小端还是大端,但它们没有,所以你不能。
如果您存储一个字节然后将其读回,您将获得相同的字节值,无论您的系统是小端还是大端位。