blog_post/_posts/大小端.md
2024-04-03 08:20:53 +08:00

69 lines
2.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 处理器大小端存储模式
tags:
- 大小端存储
categories:
- c语言
abbrlink: c25386f8
date: 2017-09-13 17:01:49
---
大端模式:是指数据的**高字节**保存在内存的**低地址**中,而数据的**低字节**保存在内存的**高地址**中。
小端模式:是指数据的**高字节**保存在内存的**高地址**中,而数据的**低字节**保存在内存的**低地址**中。
例如一个数据无符号32位整数0x12345678,其中0x12属于高字节(权值大)而0x78属于低字节(权值小),在不同的模式下存储的方式如下表:
内存地址 | 0x1000 | 0x1001 | 0x1002 | 0x1003 |
--- | --- | --- | --- | --- |
大端模式 | 0x12 | 0x34 | 0x56 | 0x78 |
小端模式 | 0x78 | 0x56 | 0x34 | 0x12 |
我们可以看得出来大端模式和我们的阅读习惯相同,权值从左往右是高位->低位而地址则是低位->高位。小端模式则是随着地址从左往右增大权值增大。地址就代表了权值的大小。
<!---more---->
利用下面c代码可以看到运行环境是如何存储一个uint数据的。
```c
#include <stdio.h>
int endian(void);
int main(int argc,char arg[])
{
unsigned int a=0x12345678;
char *ap=&a;
int i=0;
printf("0x%x storage in system is:\r\n",a);
for(i=0;i<4;i++)
printf("addr:0x%x,value:0x%x\r\n",ap+i,ap[i]);
printf("system storage by %s_endian",endian()? "Big":"Little");
return 0;
}
```
运行的结果如下,可以看出该系统是小端系统。
[![](https://s1.ax1x.com/2017/10/01/1Md81.png)](https://imgchr.com/i/1Mp4A)
我们如何简单的判断一个系统的大小端呢。我们知道**共用体(联合体)**存储在内存里是共用一块地址的,其占用空间决定于最大成员所需的空间,他们的起始地址相同。所以我们可以利用一个共用体,成员分别是一个int和一个char。通过给int赋值1然后检测char对应的值是多少如果是1代表系统将数据1放到了int的起始地址(因为char是一个字节必然在起始地址)。而起始地址是低地址低地址存放的1(权值小)推出该系统是小端系统。否则该系统是大端系统。
C代码如下
```C
int endian()
{
union{
int a;
char b;
}endunion;
endunion.a=1;
if(endunion.b==1)//如果成员b是1则证明随地址顺序和数字权值顺序相同是小端模式
return 0;//小端
return 1;//大端
}
```
还可以用一个更加简洁的办法(原理都是检测int的起始地址存放的是什么值),代码如下
```C
int endian()
{
int a=1;
return !(*((char *)&a));//取a的地址将其强制转化为char指针然后取出该地址存放的值并取反;
}
```