精华内容
下载资源
问答
  • 大小端模式

    千次阅读 2017-08-08 23:57:30
    大小端模式

    大小端模式


    什么是大小端模式


    1)大端模式,小端模式

    2)通信协议中,发送方和接收方必须按同样的字节顺序来通信,否则会出错。

    常见的,在socket通信中,常用到的函数:hton(),定义端口号或者ip地址时,需要考虑字节序。

    3)除了通信协议,在计算机存储系统中也有大小端

    一个32位的2进制在内存中存储时有两种发布方式:

    高字节  对应  高地址                --------------> 小端模式

    高字节  对应  低地址                --------------> 大端模式

    图示如下:





    大小端存在的意义


    1)在通信协议中,大小端模式是非常重要的。

    2)在实际中,有些CPU用的是大端,有些则是小端,如不加以区别的话,可能会出现读取时和储存时字节顺序不一致的情况,从而造成数据的错误。

    3)网络通信中一般为大端模式,常用计算机CPU为小端模式。



    如何判断


    用共用体union或指针可以测试出

    共用体union测试

    union myunion
    {
        int a;
        char b;
    };
    
    //
    int is_little(void)
    {
        union myunion u1;
        u1.a = 1;
        return u1.b;
    }
    
    int main(int argc, const char * argv[]) {
        // insert code here...
        
        int i = is_little();
        if (i == 1) {
            printf("little\n");
        }else{
            printf("big\n");
        }
        
        
        return 0;
    }

    图示如下:




    共用体union与结构体struct

    1)在定义和用法上很相似:

    struct mystruct
    {
        int a;
        char b;
    };
    
    
    union myunion
    {
        int a;
        char b;
        long c;
        int d[10];
    };
    int main(int argc, const char * argv[]) {
        // insert code here...
       
        struct mystruct s1;
        s1.a = 23;
        printf("s1.b = %d\n", s1.b);   // s1.b = 0
        
        union myunion u1;
        u1.a = 23;
        printf("u1.b = %d\n", u1.b);   // u1.b = 23
        printf("u1.a地址 = %p\n", &u1.a); // u1.a地址 = 0x7fff5fbff7b0
        printf("u1.b地址 = %p\n", &u1.b); // u1.b地址 = 0x7fff5fbff7b0
                                         //  说明u1.a和u1.b是共用的
        
        return 0;
    }

    2)不同之处:

    ①  结构体中的成员是相互独立的

    ②  共用体中的成员是一体的,彼此是不独立的,共使用同一个内存单元。

    共用体因为只有一个共用的空间,所以不存在内存对齐的问题

    union的大小为成员中最大的那个的大小


    指针方式测试

    int is_little(void)
    {
        int a = 1;
        char b = *((char *)(&a));
        
        return b;
    }
    
    int main(int argc, const char * argv[]) {
        // insert code here...
        
        int i = is_little();
        if (i == 1) {
            printf("little\n");
        }else{
            printf("big\n");
        }
        
        
        return 0;
    }









    展开全文
  • 目录什么是大小端模式为什么会有大小端模式之分什么情况需要考虑大小端模式常见的设备的大小端模式测试大小端模式例程 什么是大小端模式 大端模式Big-Endian:高字节存于内存低地址,低字节存于内存高地址。 小端...

    1. 什么是大小端模式

    大端模式Big-Endian:高字节存于内存低地址,低字节存于内存高地址。
    小端模式Little-Endian:低字节存于内存低地址,高字节存于内存高地址。

    网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。

    首先我们来看下数据在大小端两种模式下存储图,假设有一个整型数0x12345678,从图中可以看出明显的区别:
    在这里插入图片描述
    再给一张图便于理解:
    在这里插入图片描述

    2. 为什么会有大小端模式之分

    这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于 8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于 大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

    关于为什么会有大小端模式之分还可以从大小端两种模式各自的优缺点来分析:
    Big-Endian优点:靠首先提取高位字节,你总是可以由看看在偏移位置为0的字节来确定这个数字是 正数还是负数。你不必知道这个数值有多长,或者你也不必过一些字节来看这个数值是否含有符号位。这个数值是以它们被打印出来的顺序存放的,所以从二进制到 十进制的函数特别有效。
    因而,对于不同要求的机器,在设计存取方式时就会不同。

    Little-Endian优点:提取一个,两个,四个或者更长字节数据的汇编指令以与其他所有格式相同的方式进行:首先在偏移地址为0的地方提取最低位的字节,因为地址偏移和字节数是一对一的关系,多重精度的数学函数就相对地容易写了。
    如果你增加数字的值,你可能在左边增加数字(高位非指数函数需要更多的数字)。 因此, 经常需要增加两位数字并移动存储器里所有Big-endian顺序的数字,把所有数向右移,这会增加计算机的工作量。不过,使用Little- Endian的存储器中不重要的字节可以存在它原来的位置,新的数可以存在它的右边的高位地址里。
    这就意味着计算机中的某些计算可以变得更加简单和快速。

    3. 什么情况需要考虑大小端模式

    相同字节序的平台在进行网络通信时可以不进行字节序转换,但是跨平台进行网络数据通信时必须进行字节序转换。

    原因如下:网络协议规定接收到得第一个字节是高字节,存放到低地址,所以发送时会首先去低地址取数据的高字节。小端模式的多字节数据在存放时,低地址存放的是低字节,而被发送方网络协议函数发送时会首先去低地址取数据(想要取高字节,真正取得是低字节),接收方网络协议函数接收时会将接收到的第一个字节存放到低地址(想要接收高字节,真正接收的是低字节),所以最后双方都正确的收发了数据。

    而相同平台进行通信时,如果双方都进行转换最后虽然能够正确收发数据,但是所做的转换是没有意义的,造成资源的浪费。而不同平台进行通信时必须进行转换,不转换会造成错误的收发数据,字节序转换函数会根据当前平台的存储模式做出相应正确的转换,如果当前平台是大端,则直接返回不进行转换,如果当前平台是小端,会将接收到得网络字节序进行转换。

    4. 常见的设备的大小端模式

    STM32单片机:小端模式
    STM8:大端
    KEIL C51:大端
    x86:小端
    ARM既可以工作在大端模式,也可以工作在小端模式

    注意:大小端模式是和硬件有关的,即和芯片本身有关,IDE不能进行设置。

    5. 测试大小端模式例程

    //如果字节序为big-endian,返回true;
    //反之为   little-endian,返回false
    
    bool IsBig_Endian()
    {
        unsigned short test = 0x1234;
        if(*( (unsigned char*) &test ) == 0x12)
           return TRUE;
       else
           return FALSE;
    }//IsBig_Endian()
    

    其他例程:

    int checkCPUendian()
    {
          union{
                 unsigned long int i;
                 unsigned char s[4];
           }c;
           c.i = 0x12345678;
           return (0x12 == c.s[0]); 
    }
    

    6. 大小端转化例程

    typedef unsigned short int uint16;
    typedef unsigned long int uint32;
    // 短整型大小端互换
    #define BigLittleSwap16(A)  ((((uint16)(A) & 0xff00) >> 8) | \
     
                                 (((uint16)(A) & 0x00ff) << 8))
     
     // 长整型大小端互换
    #define BigLittleSwap32(A)  ((((uint32)(A) & 0xff000000) >> 24) | \
    
                                 (((uint32)(A) & 0x00ff0000) >> 8) | \
     
                                (((uint32)(A) & 0x0000ff00) << 8) | \
     
                                (((uint32)(A) & 0x000000ff) << 24))
    

    参考:
    https://blog.csdn.net/weixin_34088583/article/details/94191143
    https://blog.csdn.net/dongfangjing/article/details/50822143
    https://strongerhuang.blog.csdn.net/article/details/99669954

    展开全文
  • 大小端模式模式实测

    千次阅读 2019-04-05 15:45:16
    分析可知1:既然数据分高字节、低字节,说明只有数据格式是2字节以上的,才有大小端模式,比如word、dword等;而byte类型数据是不分大小端模式的。 分析可知2:有分析1可知,byte类型数据是不分大小端模式,则数据...

            大端模式,是指在内存的低地址中保存数据的高字节;而小端模式,是指在内存的低地址中保存数据的低字节。

    分析可知1:既然数据分高字节、低字节,说明只有数据格式是2字节以上的,才有大小端模式,比如word、dword等;而byte类型数据是不分大小端模式的。

    分析可知2:有分析1可知,byte类型数据是不分大小端模式,则数据格式都是统一的。即,地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。这对于大小端都是统一的格式。

             这些有点类似CAN报文:只要是跨了2个即以上字节数的CAN报文,都要考虑是Intel格式,还是Motorola格式,此时Intel格式就像小端;Motorola格式,就像大端;

    Intel格式:

     

    Motorola MSB格式:

     

    Motorola LSB格式:

    举例

    下面以unsigned int value = 0x12345678为例,分别看看在两种字节序下其存储情况,我们可以用unsigned char buf[4]来表示value

    Big-Endian: 低地址存放高字节,如下:

    低地址

    ---------------

    buf[0] (0x12) -- 高字节

    buf[1] (0x34)

    buf[2] (0x56)

    buf[3] (0x78) -- 低字节

    ---------------

    高地址

     

    Little-Endian: 低地址存放低位,如下:

    低地址

    --------------

    buf[0] (0x78) -- 低字节

    buf[1] (0x56)

    buf[2] (0x34)

    buf[3] (0x12) -- 高字节

    ---------------

    高地址

     

             此外,对于Motorola MSB和Motorola LSB的区别,可以参见上图,两者在数据的分布和处理上没有区别,唯一的区别在于对“start bit”的叫法上。比如一个12bit的数字,采用Motorola MSB和Motorola LSB格式,都是分布在从bit8~bit11、bit16~bit23的地址上,但是Motorola MSB格式说start bit为msb所在的位地址,所以为start bit:11;但是Motorola LSB格式说start bit为lsb所在的位地址,所以为start bit:16。(Intel的start bit都是按lsb所在的bit地址,所以上图中Intel的start bit:12。)

     

    如果上述没有讲清楚,还有更为详细的帖子,见如下链接:Intel格式与Motorola格式的区别

    https://blog.csdn.net/bingdianlanxin/article/details/41522373?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-1-41522373.nonecase&utm_term=motorola%E9%AB%98%E4%BD%8D%E4%BD%8E%E4%BD%8D&spm=1000.2123.3001.4430

    如有侵权请联系,谢谢

    展开全文
  • 判断机器大小端模式

    千次阅读 2017-09-24 21:43:40
    简单介绍一下大小端模式: 像内核开发,网络开发,以及嵌入式开发都要涉及以位为单位来操作,所以都要考虑大小端问题。 大端模式:数据的高位,存放在地址的低位。 小端模式:数据的高位,存放在地址的高位。 ...

    简单介绍一下大小端模式:

             像内核开发,网络开发,以及嵌入式开发都要涉及以位为单位来操作,所以都要考虑大小端问题。

    大端模式:数据的高位,存放在地址的低位。
    小端模式:数据的高位,存放在地址的高位。

    这里写图片描述

    介绍三种判断本机大小端模式的程序:

    ① 通过位移操作

    #include <stdio.h>
    #include <stdlib.h>
    
    #define panduan(x) (x>>1)?(printf("It is big endian\n")):(printf("It is litter endian\n"))
    int main()
    {
        char a = 1;
        panduan(a);
        printf("%#x\n",a);
        printf("%#x\n",a>>1);
        return 0;
    }

    这里写图片描述

    地址: 高地址 <<====== 低地址
    小端模式存放:0000 0001 >> 1 == 0000 0000
    大端模式存放:1000 0000 >> 1 == 0100 0000

    ② 通过数据类型强制转换

    #include <stdio.h>
    #include <stdlib.h>
    
    //#define panduan(x) (x>>1)?(printf("It is big endian\n")):(printf("It is litter endian\n"))
    int main()
    {
        unsigned short a = 1;
        char c = (char)a;
        //panduan(a);
        //printf("%#x\n",a);
        //printf("%#x\n",a>>1);
        printf("%#x\n",a);
        printf("%#x\n",c);
        (c)?(printf("It is litter endian\n")):(printf("It is big endian\n"));
        return 0;
    }

    这里写图片描述

    数据类型强制转换,其实本质还是取低8位数来判断。

    ③ 通过共同体

    #include <stdio.h>
    #include <stdlib.h>
    //#define panduan(x) (x>>1)?(printf("It is big endian\n")):(printf("It is litter endian\n"))
    
    typedef union test{
        int a;
        char c;
    }czg;
    int main()
    {
        czg t;
        t.a = 1;
        //unsigned short a = 1;
        //char c = (char)a;
        //panduan(a);
        //printf("%#x\n",a);
        //printf("%#x\n",a>>1);
        //printf("%#x\n",a);
        //printf("%#x\n",c);
        printf("%#x\n",t.a);
        printf("%#x\n",t.c);
        //(c)?(printf("It is litter endian\n")):(printf("It is big endian\n"));
        (t.c)?(printf("It is litter endian\n")):(printf("It is big endian\n"));
        return 0;
    }

    这里写图片描述

    和②本质上是一样的。
           共用体里面的成员共用一个内存空间,而且是从低位开始占用,共用体变量的内存空间大小是该变量中某个占用空间最大的那个成员所占的空间。比如上面的结构体变量的空间就是int a占空间的大小,char c是从低位开始占用,也就是占用int a的低8位

    展开全文
  • C语言大小端模式

    千次阅读 2018-01-07 12:56:23
    大小端模式1 大端模式(big endian)和小端模式(little endian) (1)最早出现在小说的词,和计算机无关 (2)后来用于计算机通信,在串行通信中,一次只能发送一个字节,这样发送一个int就有问题。 规则就是...
  • 大小端模式转换函数

    千次阅读 2018-11-09 00:28:22
    大小端模式转换函数
  • 大小端模式区别

    千次阅读 2017-11-11 11:34:02
    1. 什么是大端,什么是小端: 所谓的大端模式,是指数据的低位保存...为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了
  • 大小端模式的判断

    2018-09-21 09:38:56
    大小端模式的判断与示例 首先需要明确的是:采用大小端模式对数据进行存放的主要区别在于存放字节的顺序大端模式:如果计算机内存的低地址存的是数据的高字节数据,则可以判断为大端模式小端模式:如果计算机内存的...
  • Java 大小端模式

    千次阅读 2018-04-02 17:14:01
    何谓Java 大小端模式呢?所谓大端模式:指数据的高位存储在内存的低字节位,数据的低位存储在内存的高字节位。这个思维有点像一个逆向的思维。所谓小端模式:指数据的低位存储在内存的低字节位,数据的高位存储在...
  • 大小端模式与网络字节序

    千次阅读 2015-06-03 11:18:16
    一、为什么会出现大小端模式? 不同的cpu采用的大小端模式不一致。X86是小端模式。而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。 二、...
  • 正确区分大小端模式

    千次阅读 2020-03-18 15:38:52
    正确区分大小端模式 嵌入式开发经常会遇到大小端的问题,往往学习后,过一段时间就又忘记了,这里总结一下,希望给大家留下深刻的记忆。 字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端...
  • C/C++ 关于大小端模式

    2016-05-14 13:51:03
    对编译器大小端模式的判断
  • C语言测试大小端模式

    千次阅读 2017-04-27 21:45:09
    这个问题在这里不做过多解释,可以参考:大小端模式详解。 但还是给出一些基本概念: 大小端问题产生的原因:由于在各种体系结构的处理器中,对多个字节数据的内存操作有着不同的定义,所以当处理器在读写一个多个...
  • 用指针检测大小端模式

    千次阅读 2017-01-11 15:18:23
    //用指针的方式检测机器的大小端模式 int small_port() { int a = 1 ; char b = *((char *)(&a)) ; return b ; } int main(void) { int i = small_port(); if(1 == i) printf("小端模式\n"); else prin
  • 大小端模式及其验证

    千次阅读 2013-12-10 19:55:58
    大小端模式   以前对大端和小端模式一直不太了解,而且还经常弄混淆,在此,简单的总结如下: 在计算机业界,Endian表示数据在存储器中的存放顺序。 1) Little-Endian就是低位字节排放在内存的低地址端,高位字节...
  • 判断cpu大小端模式(c++代码实现)

    千次阅读 2019-11-08 09:45:27
    首先来了解一下大小端模式。           大端模式:高位对应低地址,低位对应高地址 ;换而言之,就是数字的高位存放在内存的低址地,低位存放在内存的高地址 &...
  • 文章目录大小端模式边界对齐 大小端模式 大家一定知道:多字节数据在内存里一定是占连续的几个字节 最高有效字节我们用MSB表示 最低有效字节我们用LSB表示 例如 大端模式更便于人类阅读 小端模式更便于便于...
  • 10-x86汇编——大小端模式

    千次阅读 2018-12-18 14:22:23
    汇编语言实际上是和内存以及寄存器打交道的,当处理器执行汇编指令时,影响的不是内存变化就是寄存器的变化,前面我们已经详细介绍过寄存器了,这一小节我们主要讨论数据在内存中的存储——大小端模式。 当我们对...
  • C语言怎么简单测试为大小端模式

    千次阅读 2016-07-27 19:23:28
    1、什么是大小端模式? 大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这...
  • 大小端模式,stm32采用小端模式

    千次阅读 2018-07-19 21:45:30
    存储模式:小端:较高的有效字节存储在较高的存储器地址,较低的有效字节存储...STM32 属于小端模式,简单地说:比如:temp=0X12345678;假设temp的地址为:0X4000 0000那么,在内存里面,其存储就变成了:| 地址 ...
  • 对于大小端模式的判断

    千次阅读 2014-10-18 10:37:11
    大端模式:高地址存放低字节,低地址存放高字节。...//大小端模式判断 int checkMode(){ union Test{ int i; char ch; }test; test.i=1; return test.ch; } int main(void){ in

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 267,708
精华内容 107,083
关键字:

大小端模式