【问题标题】:why endianess matters among bits inside a byte?为什么字节序在字节内的位中很重要?
【发布时间】:2013-05-16 00:45:43
【问题描述】:

以下是linux机器上库的IP结构

   struct ip
      {
    #if __BYTE_ORDER == __LITTLE_ENDIAN
        unsigned int ip_hl:4;               /* header length */
        unsigned int ip_v:4;                /* version */
    #endif
    #if __BYTE_ORDER == __BIG_ENDIAN
        unsigned int ip_v:4;                /* version */
        unsigned int ip_hl:4;               /* header length */
    #endif
        u_int8_t ip_tos;                    /* type of service */
        u_short ip_len;                     /* total length */
        u_short ip_id;                      /* identification */
        u_short ip_off;                     /* fragment offset field */
    #define IP_RF 0x8000                    /* reserved fragment flag */
    #define IP_DF 0x4000                    /* dont fragment flag */
    #define IP_MF 0x2000                    /* more fragments flag */
    #define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
        u_int8_t ip_ttl;                    /* time to live */
        u_int8_t ip_p;                      /* protocol */
        u_short ip_sum;                     /* checksum */
        struct in_addr ip_src, ip_dst;      /* source and dest address */
      };

对于这些行:

    #if __BYTE_ORDER == __LITTLE_ENDIAN
        unsigned int ip_hl:4;               /* header length */
        unsigned int ip_v:4;                /* version */
    #endif
    #if __BYTE_ORDER == __BIG_ENDIAN
        unsigned int ip_v:4;                /* version */
        unsigned int ip_hl:4;               /* header length */
    #endif

为什么字节序在字节内很重要? 我认为字节序只影响多字节整数,但在我看来字节序也会影响字节内的位排列?

另外,它只是一个字节,为什么是unsigned int,也就是4个字节。

我注意到在wireshark 中,ip_v 和ip_hl 显示为0x45 如果我捕获一个 IP 数据包。第一个字节由 ip_v 和 ip_hl 组成 我把它放到一个字符变量x

那么x & 0b11110000 的结果是什么?不管是什么字节序,它总是 4,还是可能是 5?

【问题讨论】:

  • x & 0b11110000 的结果是什么?不管是什么字节序,它总是 4,还是可能是 5?
  • 是的,0x45 & 0b1110000 的结果总是0x40,不管字节序是什么。但是,编译器可以按任意顺序放置位字段(“冒号四”:4 事物)。因此,如果您分配ip_hl=4, ip_v=5,您可能会得到0x450x54,具体取决于编译器(编译器在决定半字节的字节序时通常会遵循字节的字节序)。

标签: c bit endianness


【解决方案1】:

存在与多字节数据相关的字节顺序。但在您的情况下,重要的是bit field ordering,它处理单字节数据的位顺序。 C 标准没有提出关于位字段排序的规则。它取决于实现并由编译器决定。

变量的大小不是 4 个字节。它只有 4 位。它们不是自变量。它们是结构中的位域。

【讨论】:

  • 只有一个字节,为什么是unsigned int类型,是4个字节。
  • "unsigned int" 后跟冒号和一个整数,如"unsigned int ip_v:4",是位域的声明。如果有帮助,请将其视为“大小为 4 位的无符号整数”(严格来说,在声明位字段时不能使用其他类型)。
【解决方案2】:

字节序定义了最高有效位 (MSB) 的位置,它与变量内的数字在内存中的解释方式有关。考虑无符号整数:

00000001 (Binary) = 1 (2 to the power of 0) -> If the most significant bit is to the left

00000001 (Binary) = 128 (2 to the power of 7) -> If the most significant bit is to the right

正如您所见,最高有效位的位置对于内存中的数字表示非常重要,即使在 8 位数字中也是如此。

对于你的最后一个问题,你是对的,它是 1 字节还是 4 没有区别,因为它只占用 4 位。但请记住,无符号 int 并不总是 4 字节数。

希望对你有帮助!

【讨论】:

  • then what is the result of x & 0b11110000 ? is it always 4 no matther what endianess, or it may be 5? 怎么样我真的很困惑这个
  • 这是误导。就 C 而言,二进制 00000001 (0x01) 以 10 为底总是 1。例如,右移运算符 >> 削减(正)数字(大约)减半,不会加倍:4>>1 == 2。正如其他人指出的那样,字节顺序是位域。 §6.7.2.1,标准的第 11 段规定 order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined.
  • 但问题不在于 C 中的字节序,当然,在几乎所有计算机语言中,同一指令在不同硬件中的行为方式都相同。如果您注意代码,它似乎正在处理来自硬件接口的数据 -> 不同的硬件可以有不同的字节序 -> 字节序很重要
  • 问题是关于 C 中的字节顺序,因此是 C 代码和标签。在标准 C 中,您无法寻址特定位。直接访问它们的唯一方法是使用移位、按位运算和位域。该标准要求数字看起来好像 MS 位是“第一个”。无论底层硬件的位顺序如何(如果适用的话),翻译者有责任确保这一点。位域可以从任一端开始,但结果值仍然是 MSB 优先的。网络和通信协议可能会以 LSB 优先传输,但这并不意味着它们在 C 中就是这样存储或访问的。
  • 这个答案完全不正确。请参阅下面的stackoverflow.com/questions/864077/… 和 Deepu 的回答。字节顺序作为一个概念通常不涉及位的顺序,但某些实现可能会根据字节顺序翻转位顺序,只是出于他们自己的判断。
猜你喜欢
  • 1970-01-01
  • 2017-06-06
  • 1970-01-01
  • 2010-10-26
  • 1970-01-01
  • 2016-02-15
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
相关资源
最近更新 更多