【问题标题】:How does this code that tests for a system's Endianess work?测试系统 Endianess 的代码如何工作?
【发布时间】:2013-10-09 04:55:55
【问题描述】:

所以我试图通过使用代码找出系统使用的字节序。上网查了一下,发现有人有同样的问题,Stack Exchange上的一个答案,代码如下:

int num = 1;
if(*(char *)&num == 1)
{
    printf("\nLittle-Endian\n");
}
else
{
    printf("Big-Endian\n");
}

但是这个人没有解释为什么会这样,我也不能问。以下代码背后的原因是什么?

(*(char *)&num == 1)

【问题讨论】:

    标签: memory system


    【解决方案1】:

    我假设您使用的是 C/C++

    1. &num 获取整数 num 在内存中的地址。
    2. 它将地址解释为一个指向char的指针 (char *)
    3. 接下来,这个指向 char 的指针的值由*(char *)&num 中的第一个星号考虑并进行比较 到 1。

    现在int 是 4 个字节。在大端系统上是00 00 00 01,在小端系统上是01 00 00 00。一个 char 只有一个字节,因此转换为 char 的值将占用num 占用的内存的第一个字节。所以在大端系统上,这将是**00** 00 00 01,在小端系统上,这将是**01** 00 00 00。 因此,现在您使用 if 语句进行比较,以确定转换为 char 的 int 是否等同于在 little endian 系统上使用的字节顺序。

    在 X86 32 位系统上,这可以编译为以下程序集

    mov     [esp+20h+var_4], 1      ; Moves the value of 1 to a memory address
    lea     eax, [esp+20h+var_4]    ; Loads that memory address to eax register
    mov     al, [eax]               ; Takes the first byte of the value pointed to by the eax register and move that to register al (al is 1 byte)
    cmp     al, 1                   ; compares that one byte of register al to the value of 1
    

    【讨论】:

    • 我喜欢你的回答,现在我明白了,但我还有一个问题,为什么在你的示例中一个字节表示为两个零?我最初的想法是一个字节将表示为 8 个零?
    • @Rouke 很容易将一个字节视为十六进制值的 00 到 0xFF 范围内。当您使用反汇编程序时,您会看到以十六进制值而不是十进制值格式化的 CPU 寄存器。因为 CPU 占用了跨越 4 个字节的值 (int) 的第一个字节(转换为 char),所以在您的代码中,更容易想象这种方式实际发生了什么。
    • @Rouke My original thought was that one byte would be represented as 8 zeros 一个字节有 8 位。因此,如果您以二进制显示一个字节,您确实会有 00000000(八)个位置。每个 0 可以是 1,因此最大值可以是 11111111,即十六进制的 0xFF 和十进制的 255。所以int num 将被写成 binary 4 个 8 位块,值为 1 时将是 00000000 00000000 00000000 00000001。
    【解决方案2】:
    (*(char *)&num == 1)
    

    大致翻译为取变量num的地址。将其内容转换为一个字符并将其值与 1 进行比较。

    如果整数的第一个地址的字符是 1,那么它是低位字节,并且你的数字是 Little-Endian。

    Big-Endian 数字将在最低地址具有高位字节(如果整数值为 1,则为 0),因此比较将失败。

    【讨论】:

      【解决方案3】:

      我们都知道类型“int”占用4个字节,而“char”只有1个字节。 该行只是将整数转换为 char。它相当于:char c = (char)"the minimum byte of num"。

      查看字节序的概念:http://en.wikipedia.org/wiki/Endianness

      那么如果宿主机是big-endian,c的值为0,否则为1。

      一个例子是: 假设 num 为 0x12345678,在 big-endian 机器上,c 为 0x12,而在 little-endian 机器上 c 为 0x78

      【讨论】:

        【解决方案4】:

        来了。您将值 1 分配给一个 4 字节的 int 所以

        01 00 00 00 在小端 x86 上 00 00 00 01 大端

        (*(char *)&num == 1)

        &num 给出了 int 的地址,但转换为 char* 将读取(取消引用)限制为 1 个字节(char 的大小)

        如果第一个字节是 1,那么最低有效位在前,它是小端。

        【讨论】:

          猜你喜欢
          • 2011-07-16
          • 2012-04-15
          • 1970-01-01
          • 1970-01-01
          • 2015-05-26
          • 2013-10-17
          • 2017-10-10
          • 1970-01-01
          • 2015-11-15
          相关资源
          最近更新 更多