Странное поведение при использовании указателей

У меня есть файл с некоторыми двоичными данными следующим образом.

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

Это инвертированный результат по сравнению с первым результатом. Я использую обычный процессор Intel. Почему такое поведение? Ожидается ли это.


person liv2hak    schedule 28.08.2013    source источник
comment
Вы знаете, что такое Endianness? Посмотрите вокруг на этом сайте. есть десятки вопросов, связанных с ним (например, этот.   -  person WhozCraig    schedule 29.08.2013
comment
Intel == обратный порядок байтов.   -  person Ed S.    schedule 29.08.2013


Ответы (2)


В вашем коде, который сдвигает значение, вы читаете самый старший байт из самого младшего адреса (биты 40-47 со смещения 0). Я предполагаю, что ваш второй случай работает на машине x86, таким образом, читая младший байт с самого младшего адреса (поскольку так определяется x86, как и МНОГИЕ другие процессоры, они называются машинами с «младшим порядком байтов»).

Если вам нужны байты именно в таком порядке, на машине с прямым порядком байтов вам придется получать байты один за другим и выполнять сдвиг (если вам нужно целое 64-битное значение, можно было бы использовать инструкцию перестановки байтов на x86, но я сомневаюсь, что этого достаточно, когда вам нужно «отменить» это, сдвинув и маскируя 16 бит, которые вам на самом деле не нужны).

person Mats Petersson    schedule 28.08.2013

Поведение ожидаемое.

Порядок байтов целого числа сохраняется в памяти разным. От младшего значащего байта к старшему (Little endian) или от старшего значащего байта к наименьшему. (старший порядок байтов).

Погуглите "endian" для тонны информации или прочитайте "Guliver Travel's".

person chux - Reinstate Monica    schedule 28.08.2013