【问题标题】:Strange behaviour when using pointers使用指针时的奇怪行为
【发布时间】:2013-08-28 22:13:36
【问题描述】:

我有一个包含一些二进制数据的文件,如下所示。

aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55         
aa 55 aa 55 36 65 fb 5f 1e 92 d8 1b 55 f7 fb 5f         
1e 92 d8 1b

我想提取值55 36 65 fb 5f 1e

如果我使用以下代码。

temp_1 = (data_ptr[offset]);
val = temp_1 << 40;

temp_1 = (data_ptr[offset + 1]);
val |= temp_1 << 32;

temp_1 = (data_ptr[offset + 2]);
val |= temp_1 << 24;

temp_1 = (data_ptr[ts_offset + 3]);
val |= temp_1 << 16;

temp_1 = (data_ptr[ts_offset + 4]);
val |= temp_1 << 8;

temp_1 = (data_ptr[ts_offset + 5]);
val |= temp << 0;

printf("read value %"PRIx64" \n",val);

这个 printf 的输出是

3665fb5f1e92

现在我也尝试使用单个 64 位 ptr cast 操作来计算相同的值。

val = *(uint64_t*)(data_ptr + ts_offset);
printf("read value %"PRIx64" \n",val);

上面代码的输出是

1bd8921e5ffb6536 

如果您在此处检查最低有效 48 位 921e5ffb6536

与第一个结果相比,它是倒置的。我使用的是普通的英特尔处理器。为什么会出现这种情况?这是预期的吗?

【问题讨论】:

  • 你知道Endianness是什么吗?在这个网站上四处看看。有几十个与之相关的问题(例如this one.
  • 英特尔 == 小端。

标签: c pointers pointer-arithmetic


【解决方案1】:

在移动值的代码中,您正在从最低地址(偏移量 0 的第 40-47 位)读取最高字节。我猜你的第二种情况是在 x86 机器上运行,因此从最低地址读取最低字节(因为这就是 x86 的定义方式,就像许多其他处理器一样,它们被称为“小端”机器)。

如果您想要特定顺序的字节,在 little-endian 机器上,您必须一个接一个地获取字节并移位(如果您想要一个完整的 64 位值,可能已经可以使用x86 上的 byteswap 指令,但我怀疑它是否足够有价值,因为当您需要通过移动和屏蔽您实际上不需要的 16 位来“撤消”它时)。

【讨论】:

    【解决方案2】:

    这种行为是预期的。

    一个整数在内存中保存的字节顺序是不同的。从最低有效字节到最高(小端)或最高有效字节到最低。 (大端)。

    谷歌“endian”获取大量信息或阅读“Guliver Travel's”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-22
      • 2019-05-05
      • 2020-11-28
      • 2021-07-01
      • 2013-03-31
      • 2019-04-27
      • 2012-05-29
      相关资源
      最近更新 更多