В настоящее время я сталкиваюсь с проблемой, о которой я понятия не имею, как ее избежать ..
Я пытаюсь обрабатывать данные, которые могут быть как с прямым порядком байтов, так и с прямым порядком байтов. На самом деле это не проблема, потому что он всегда начинается с заголовка, поэтому я могу проверить, какой порядок байтов мне нужно использовать, но во время декодирования значений есть некоторые операции, которые я не знаю, как реализовать для данных с прямым порядком байтов.
Код работает на nVidia Tegra (Cortex-A9, основанном на архитектуре ARMv7), который имеет младший порядок (или работает в режиме с прямым порядком байтов), но иногда я получаю данные с прямым порядком байтов.
Большинство операций с данными на самом деле не проблема, но я не знаю, как правильно добавить сложение.
Example: D5 1B EE 96 | 96 EE 1B D5
+ AC 84 F4 D5 | + D5 F4 84 AC
= 1 81 A0 E3 6B | = 1 6C E2 A0 81
Как вы можете видеть, большинство байтов уже верны в результате, но некоторые нет. Они отличаются на +1 или -1 от ожидаемого результата, потому что сложение всегда производится справа налево (машина с прямым порядком байтов), и поэтому мы переносим перенос (если есть) слева.
В случае сложения с прямым порядком байтов на этой машине с прямым порядком байтов я должен был бы добавить слева направо и перенести перенос (если есть) вправо.
Мой вопрос сейчас таков: есть ли возможность (возможно, с использованием специальных инструкций для процессора?) Получить правильный результат? Может быть, есть дальнейшие операции, которые я могу сделать для результата, чтобы избавиться от этих различий + 1 / -1, которые «дешевле», чем отменить оба операнда, а также результат?
С уважением,
Тобиас
Наиболее логичный способ сделать это — просто преобразовать числа в правильные порядковые номера, затем выполнить вычисление, а затем (при необходимости) преобразовать обратно.
Конечно, вы могли бы использовать цикл для выполнения побайтной обратной подсчета и обработки переноса — но это более сложно, и я уверен, что это тоже не будет быстрее, потому что есть больше условных выражений и процессоров. довольно хорош в «byteswapping».
Вы должны быть в состоянии использовать ntohl
а также htons
сетевые функции для преобразования чисел.
Что-то вроде этого:
int add_big_endian(int a, int b)
{
x = ntohl(a);
y = ntohl(b);
z = x + y;
return htonl(z);
}
У вас есть два варианта: вы можете написать два набора кода, по одному для каждого порядка байтов, и попытаться отслеживать, что и где происходит, или вы можете использовать одно внутреннее представление и соответствующим образом преобразовывать входящие и исходящие значения. Последнее намного проще.