Это упрощено из более крупного примера.
В исходнике C у меня есть:
uint32_t xx = oxdeadbeef ;
Я скомпилировал с помощью gcc -O или clang -O.
Глядя на «objdump -d a.out» на RPi 4, я вижу
9ac: 5297dde8 mov w8, #0xbeef // #48879
9b0: 72bbd5a8 movk w8, #0xdead, lsl #16
Это дает правильный результат, но это 16-битные значения. Как заставить gcc или clang использовать 32-битную версию в этом случае?
mov w8, #0xdeadbeef
Или я хочу?
uint32_t xx = oxdeadbeef ;
Я на 100% уверена, что у вас его нет.
Все инструкции ARM64 имеют ширину 32 бита, в отличие от x86, где они имеют переменную длину. Поскольку вам нужно несколько битов для опкода и спецификатора регистра, из этого следует, что вы не можете закодировать все возможные mov wn, #imm32
в одной инструкции. Поэтому вместо этого дизайнеры архитектуры ограничили его 16 битами и предусмотрели movk
, чтобы было достаточно удобно создавать большее значение с помощью нескольких инструкций. У нас определенно были и другие вопросы по этой проблеме, но я не могу найти действительно «канонический», на который можно было бы ссылаться как на обман. Возможно, когда-нибудь я напишу один.
mov - это не настоящая инструкция .
Этот микроконтроллер не имеет возможности немедленного перемещения 32-битного значения в регистр, только 16 бит. 2 инструкции быстрее и короче, чем сохранение значения в памяти и загрузка его в регистр из памяти.
Вот почему у вас есть 2 инструкции.
Вы уверены, что такая инструкция (а не псевдоинструкция) действительно существует в этой архитектуре?