Проблема с использованием 64-битных данных в 32-битном процессоре (ARM Cortex A9) - PullRequest
1 голос
/ 16 июня 2019

Прежде всего, контекст: я реализую программу на процессоре ARM Cortex A9.У меня была проблема, связанная с самим кодом C, которая была решена здесь: Как установить значения массива в одну переменную

Сначала я написал код на своем компьютере (ОС Linux64 бита) и принятый ответ по вышеуказанной ссылке работает.Однако, когда я сделал то же самое в ARM A9, это не так.Я сделал простой тест на ARM:

uint64_t test = 0x1B26B354A1CF;
printf("%lx", test);

он печатает:

d

То же самое на моем компьютере:

 uint64_t test = 0x1B26B354A1CF;
 printf("%lx \n", test);

печатает:

1b26b354a1cf

Так что это похоже на проблему переполнения или обработку таких «больших» данных.Как мне найти обходной путь или альтернативное решение для этого?

Цель: ARTY Z7 FPGA (в этой задаче вы можете игнорировать часть "FPGA". Я просто работаю с процессором, имеющимся на этой плате: ARMA9 CORTEX)

Ответы [ 3 ]

4 голосов
/ 16 июня 2019

В вашем коде две проблемы:

  1. Вы не знаете, какой суффикс использовать для определения литерала uint64_t на целевой платформе.

  2. Вы не знаете, какой спецификатор формата использовать в printf для значений uint64_t на целевой платформе.

Оба могут быть решены с помощью с использованием макросов, определенных в stdint.h .

В частности, чтобы определить литерал и присвоить его переменной:

uint64_t test = UINT64_C(0x1B26B354A1CF);

Для печати шестнадцатеричного значения переменной в printf:

printf("%" PRIx64 "\n", test);

Это гарантированно работает на любой платформе, которая должным образом поддерживает uint64_t, независимо от того, сколько бит его процессор.

Хотя сам язык не требует от вас использования суффикса для целочисленных литералов в большинстве случаев - заметное исключение - использование литерала непосредственно в качестве аргумента для функции с переменными числами, такой как printf - это делается в явном виде является хорошей практикой в ​​целом и может быть обязательной в руководящих принципах кодирования проектов, важных для безопасности. Например, правило 10.6 руководства MISRA C: 2004 требует использования суффикса U для всех беззнаковых констант.

1 голос
/ 16 июня 2019

Для обычного printf (и семейства) формат для печати unsigned long long (что, скорее всего, uint64_t) в шестнадцатеричном формате - "%llx".Обратите внимание на дополнительный префикс размера l.

Несоответствие спецификатора формата и типа аргумента приводит к неопределенному поведению .

Наиболее вероятно, что long равно 32биты в вашей 32-битной системе и 64-битные в вашей домашней системе, поэтому кажется, что она работает в вашей домашней системе.

0 голосов
/ 16 июня 2019

Что касается суффикса для определения 64-разрядного литерала без знака, вы можете проверить, какой суффикс используется в вашем stdint.h для #define UINT64_MAX. В моем случае, макрос под названием __UINT64_C(c) используется для вставки суффикса UL после литерала, если размер моего слова равен 64, или ULL, если размер моего слова равен 32.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...