我有一个带有一些二进制数据的文件如下。
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强制转换操作来计算相同的值。
val = *(uint64_t*)(data_ptr + ts_offset);
printf("read value %"PRIx64" \n",val);
上述代码的输出是
1bd8921e5ffb6536
如果你在这里检查最不重要的48位921e5ffb6536
与第一个结果相比,它是倒置的。我正在使用普通的英特尔处理器。为什么这种行为?这是预期的。
答案 0 :(得分:2)
在移动值的代码中,您正在读取最低地址的最高字节(偏移0处的位40-47)。我猜你的第二种情况是在x86机器上运行,因此从最低地址读取最低字节(因为这是x86的定义方式,就像许多其他处理器一样,它们被称为“little-endian”机器)。
如果你想要那个特定顺序的字节,在little-endian机器上,你将不得不逐个获取字节并移位(如果你想要一个完整的64位值,它可能已经可以使用在x86上的byteswap指令,但我怀疑它是否足够值,因为当你需要通过移动和屏蔽你实际上不需要的16位来“撤消”它。
答案 1 :(得分:1)
预期会有这种行为。
整数的字节顺序保存在内存中会有所不同。从最低有效字节到大多数(小端)或最高有效字节到最小。 (大端)。
Google“endian”获取大量信息或阅读“Guliver Travel's”。