zoukankan      html  css  js  c++  java
  • CPU的大小端模式

    不同体系结构的CPU,数据在内存中存放的排列顺序是不一样的。
    存储器中对数据的存储是以字节(Byte)为基本单位的,因此,字(Word)和半字(Half-Word)在存储器中就有两种次序,分别称为:大端模式(Big Endian)小端模式(Little Endian)

    大端存储模式是指字或半字的最高字节(Most Significant Bit,MSB)存放在内存的最低位字节地址上,而字数据的低字节则存放在高地址中。打个比方,有一个字为0x12345678,这个字由4个字节组成,从高位到低位的次序为:0x12,0x34,0x56,0x78。如果把这个字存放在以0x00000000起始的内存中,这个字在内存中的实际存放情况如下表:

    内存地址

    存储的数据(Byte)

    0x00000000

    0x12

    0x00000001

    0x34

    0x00000002

    0x56

    0x00000003

    0x78

    0x00000004

    ……

    大端模式的次序就像是我们平时书写的次序,先写大数,后写小数。另外,大端存储次序还广泛运用在TCP/IP协议上,因此又称为网络字节次序

    小端存储模式是指字或半字的最低位字节(Lowest Significant Bit,LSB)存放在内存的最低位字节地址上,而字数据的高字节则存放在高地址中。还以0x12345678为例,在小端模式下存储如下表所示:

    内存地址

    存储的数据(Byte)

    0x00000000

    0x78

    0x00000001

    0x56

    0x00000002

    0x34

    0x00000003

    0x12

    0x00000004

    ……

    需要注意的几点是:

    (1)   数据在寄存器中都是以大端模式次序存放的。

    (2)   对于内存中以小端模式存放的数据。CPU存取数成时,小端和大端之间的转换是通过硬件实现的,没有数据加载/存储的开销。

     

    例题1:

     

    int main()

    {

    long long a=1;

    long long b=2;

    long long c=3;

    printf("%d,%d,%d",a,b,c);

    return 0;

    }

    输出结果是什么?(32位环境,cpu为小端模式,所有参数用栈传递)

     

    解答:

    3264上面, long long都是8字节,小端模式是将数据的低位字节存放在内存的低位地址上。printf("%d  %d  %d ", a, b, c)依次将c , b, a三个long long型的数据压入栈中,然后以d%的格式输出,会依次从a的地址开始输出3个整型数据(4B)一共是12B,调用printf时参数从右至左压栈,压栈顺序是cba且地址是连续存放的,小端情况下从a开始的栈去内存内容如下:

    0x 01 00 00 00 00 00 00 00 

    0x 02 00 00 00 00 00 00 00 

    0x 03 00 00 00 00 00 00 00

    所以连续输出12个字节的结果就是:1 0 2

     

    知道了大小端模式的概念,但如果让我们用C语言写段代码判断一个CPU是大端模式还是小端模式应当如何做呢 ?

    要用C语言简洁的实现就要用到联合体(union),简单的说union就是一种结构,在union中所有的数据成员共用一个存储空间,在同一时间只能存储其中的一个数据成员,所有的数据成员具相同的起始地址,相对于基地址的偏移量都为0;

    采用union来判断,具体代码如下:

    1. int CheckEndian(void)  
    2. {  
    3.     union check  
    4.     {  
    5.         int  Word;  
    6.         char Half;  
    7.   
    8.     } Endian;  
    9.   
    10.     Endian.Word=1;  
    11.   
    12.     if(1 == Endian.Half)  
    13.         return Little_Endian;  
    14.     else   
    15.         return Big_Endian;  
    16. }  
  • 相关阅读:
    Ubuntu中用户名密码和root密码修改
    在Python中,输出格式:%d , %6d , %-6d, %06d , %.6f的一些区分
    定制的print()输出格式
    python编程系列---Pycharm快捷键(更新中....)
    webbrowser控件——Windows下的开发利器
    Windows读写文件的猫腻
    根据GUID获取设备信息
    转:APDU命令格式
    VC中添加消息响应函数
    VC 取消warning
  • 原文地址:https://www.cnblogs.com/0YHT0/p/3403474.html
Copyright © 2011-2022 走看看