操作系统的大小端模式

 
什么是大小端模式
大小端存储由 CPU架构 决定。
大端模式( big endian :低地址存在高位,高地址存在低位;
小端模式( Little Endian :低地址存在低位;高地址高位;
例如:
使用大端模式的有:Mac OS、PowerPC、IBM、Sun、 TCP/IP网络数据流
使用小端模式的有:x86、Linux
而ARM可以是大端模式,也可以是小端模式;
 
 
如何判断CPU是大端模式还是小端模式
// liunx内核的方法
void check_CPU_mode_1()
{   // union共享同一段内存;
    // 对齐方式需适合其中所有的成员,即大小能被其包含的所有基本数据类型的大小所整除。
    static union{
        char c[4];
        unsigned long mylong; // unsigned long 为4个字节
    }endian_test = { {'L','?','?','B'} };
    #define ENDIANNESS  ( (char)endian_test.mylong )
    if ( 'b' == ENDIANNESS )
        printf(" it's Big endian\n");
    else
        printf("it's Little endian\n");
}
// 指针方法
void check_CPU_mode_2()
{    
    int a = 1;
    unsigned char *p = (unsigned char*)(&a); // p指向指向a地址最低一个字节
    if( *p == 1)
        cout << "CPU使用小端模式存储\n";
    else
        cout << "CPU使用大端模式存储\n";
}
 
用宏实现大小端转换
/*  定义多行宏时在每一行后面加 '\' */
//对于16位数据
#define BigtoLittle16(A) (( ((uint16)(A) & 0xff00) >> 8)| \
                            (( (uint16)(A) & 0x00ff) << 8))
//对于32位数据
#define BigtoLittle32(A)   ((( (uint32)(A) & 0xff000000) >> 24) | \
                            (( (uint32)(A) & 0x00ff0000) >> 8)   | \
                            (( (uint32)(A) & 0x0000ff00) << 8)   | \
                            (( (uint32)(A) & 0x000000ff) << 24))
 
 
 
数组在大小端情况下的存储情况
若存在unsigned int value = 0x12345678,用unsigned char buf[4]来表示value,则
操作系统的大小端模式_第1张图片
操作系统的大小端模式_第2张图片
 
 
例题1
假设在一个 32 位 little endian 的机器上运行下面的程序,结果是多少?
#include
int main()
{
    long long a = 1, b = 2, c = 3;// long long 4字节 = 32bit
    printf("%d,%d,%d\n", a, b, c);  // %d格式输出的是4个字节大小
    return 0;
}
输出结果为:1,0,2 
 
小端模式,a端为低地址,c端为高地址,long long 为8字节,a=0x01,b=0x02,c=0x03
注:printf()是一个库函数,C,C++中函数的参数是从右往左入堆栈的,再弹出;%d格式输出的是4个字节大小,
 
小端模式
0x03
c
0
3
0x02
b
0
2
0x00
a
0
1
 
若存在数据 A = ‭305419896‬,十六进制表示为:0x12345678
 
大端模式
内存地址
 
HEX数位
0x03
 
78
0x02
56
0x01
 
34
0x00
12
一个字节地址空间占8个位(bit),而一个十六进制数据位占4位(bit), 所以一个内存地址可以存两个十六进制数据位
 
 
 
例题2
int main()
{
    unsigned int value = 1024;  // 4 个 字节  
    cout << hex << &value << endl;
    
    bool *p = (bool*)(&value); 
    cout << hex << p << endl;
    
    p++;// p 指向 value地址, 不过移动的话按 bool 步长移动
    cout << p << endl;
    
    bool condition = *((bool *)(&value));  //(bool *)(&value);取的是第一位的地址
    if (condition)
        printf("condition=1");
    else
        printf("condition=0");        
}
unsigned int 为4个字节, 1024 = 0x0000 0400
注: 涉及地址间的强制类型转换;16进制分析;大小端模式分析;
小端模式
大端模式
高地址
00
 
00
 
00
 
04
 
04
 
00
低地址
00
 
00
 
 
 
 
 
 
 
 
 

你可能感兴趣的:(C/C++,Linux,大端模式,小端模式)