TypeCodes

C语言字节序的大小端模式

关于字节序的大小端模式,个人认为CSDN上Hackbuteer1作者的这篇文章《大端模式和小端模式》讲解的很清晰。这里MARK一下自己的学习心得:

C程序内存映射模式

1 原文精华
小端模式[Little-Endian]:内存块低地址存放元素的低位(字节),内存块高地址存放元素的高位(字节)
大端模式[Big-Endian]:内存块低地址存放元素的高位(字节),内存块高地址存放元素的低位(字节)

采用小端模式的处理器包括:PDP-11、VAX、Intel系列微处理器和一些网络通信设备; 采用大端模式的处理器包括:IBM3700系列、PDP-10、Mortolora微处理器系列和绝大多数的RISC处理器

2 关于主机序(小端模式)和网络字节序(大端模式)

两台主机之间通过TCP/IP协议进行通信的时候,在向对方发送报文前,都需要调用相应的函数把自己的主机序(Little-Endian)模式的报文转换成网络序(Big-Endian)模式;同样,在接收到对方的报文信息后,都需要将报文(网络序)转换成主机序(Little-Endian)。

3 通过共用体、十六进制整数、字符数组判断CPU的大小端模式

下面通过三种途径来判断自己的系统的CPU处理器的模式,部分代码改自原文《大端模式和小端模式》。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>

//通过共用体检测CPU的大小端模式
int checkCPU()
{  
    short int test = 0x1234;

    if( *((char *)&test) == 0x12 )     //低地址存放高字节, 则是大端模式
        return 1;  
    else
        return 0;  
}

int main( int argc, char * argv[] )
{
    /* 1 通过共用体判断大小端模式 */
    if( checkCPU() )
        printf("Big endian.\n\n");
    else
        printf("Little endian.\n\n");

    /* 2 用十六进制整型数据判断大小端模式 */
    short int a = 0x1234;
    char x0 , x1, x2;

    x0 = ( (char *)&a )[0];
    x1 = ( (char *)&a )[1];
    printf( "x0=[%c], x1=[%c]\n", x0, x1 );
    if( x0 == 0x34 && x1 == 0x12 )
        printf("Little endian.\n\n");
    else
        printf("Big endian.\n\n");

    /* 3 用字符数组判断大小端模式 */
    char b[] = "abc";
    x0 = b[0];
    x1 = b[1];
    x2 = b[2];
    printf( "x0=[%c], x1=[%c], x2=[%c]\n", x0, x1, x2 );
    if( x0 == 'a' && x1 == 'b' && x2 == 'c' )
        printf("Little endian.\n");
    else
        printf("Big endian.\n");

    return 0;
}

由于自己用的是win7系统,处理器当然是Intel的CPU,所以作为小端模式输出结果如下图所示:

C语言win7系统CPU大小端模式

4 通过上面代码总结分析大、小端模式
4.1 关于栈“先进后出,后进先出”的原理:

C/C++程序在内存中的映射,栈是向下增长的,即栈底在上(高地址),栈顶在下(低地址);而堆是向上增长的。“入栈”时:元素从栈顶压入,压入后,该元素变成高字节(高位),然后栈顶向低地址下降(即向下增长),然后继续从栈顶压入第二个元素,同时第一个压入的元素变成栈底依次重复;“出栈”时:元素从栈顶弹出,弹出后,栈顶的地址也随之改变,指向下一个元素的位置,依次重复,直到到达栈底

4.2 分析代码中用整型数据判断大小端模式:

短整型数据a = 0x1234;,它的高字节(高位)是0x12,低字节(低位)是0x34。因为栈是从高地址向低地址增长的,即栈底对应于高地址,栈顶对应于低地址,对应x[0]是低地址,x[1]是高地址。所以如果是小端模式,即低地址放低字节(低位),高地址放高字节(高位),那么低地址x[0]应该等于 0x34(为ASCII中字符'4'),高地址x[1]等于0x12(为ASCII中不可打印的字符DC2)。

4.3 分析代码中用字符数组判断大小端模式:

对于字符串常量abc,其字节(位)从左往右按顺序由低到高,即字符'a'是低字节(位),字符'c'是高字节(位),这点和前面的短整型高低位从左到右是依次降低的不同。因此,对于小端模式,入栈的时候,字符'c'先入栈,然后是字符'b',最后是字符'a'。这样字符'c'位置成为栈底,字符'a'的位置成为栈顶。即x[0]存放低字节(位)'a',低地址x[1]存放低字节(位)'b',高地址x[2]存放高字节(位)'c'。

打赏支持

Comments »