Мир ARM немного запутан.
Для программистов на C все просто: все архитектуры ARM предлагают обычную 32-битную модель программирования с плоской адресацией.Пока вы остаетесь с исходным кодом C, единственное отличие, которое вы можете увидеть, - это порядковый номер и производительность.Большинство процессоров ARM (даже старые модели) могут быть как с прямым порядком байтов, так и с прямым порядком байтов;выбор тогда сделан платой логики и операционной системой.Хороший C-код endian-нейтральный : он компилируется и работает правильно, независимо от порядкового номера платформы (endian-нейтральность хороша для надежности и удобства обслуживания, но также и для производительности: ненейтральный код - это код, который обращается к тем же даннымчерез указатели разных размеров, и это наносит ущерб строгим правилам алиасинга, которые компилятор использует для оптимизации кода).
Ситуация совершенно иная, если учесть совместимость бинарную (то есть повторное использование кодакоторый был скомпилирован один раз):
- Существует несколько наборов команд:
- исходный набор команд ARM с 26-битным счетчиком программ (очень старый, очень маловероятныйв наше время)
- набор команд ARM с 32-разрядным программным счетчиком (часто называемый «кодом ARM») *
- набор команд Thumb (16-разрядные упрощенные коды операций)
- набор команд Thumb-2 (Thumb с расширениями)
Данный процессор можетдополняют несколько наборов инструкций.Новейшим процессором, который знает только код ARM, является StrongARM, представитель ARMv4, которому уже достаточно лет (15 лет).ARM7TDMI (архитектура ARMv4T) знает как ARM, так и Thumb, как и почти все последующие системы ARM, за исключением Cortex-M.Код ARM и Thumb могут быть смешаны вместе в одном приложении, при условии, что вставляется соответствующий клей в случае изменения соглашений;это называется совместное использование большого пальца и может обрабатываться автоматически компилятором C.
Cortex-M0 знает только инструкции Thumb.Он знает несколько расширений, потому что в «обычных» процессорах ARM операционная система должна использовать код ARM (для обработки прерываний);таким образом, Cortex-M0 знает несколько вещей Thumb-for-OS.Это не имеет значения для кода приложения.
Другой Cortex-M знает только Thumb-2.Thumb-2 в основном обратно совместим с Thumb, по крайней мере, на уровне сборки.
- Некоторые архитектуры добавляют дополнительные инструкции.
Таким образом, если какой-то код скомпилирован с переключателем компилятора, говорящим, что это для ARMv6, то компилятор может использовать одну из немногих инструкций с ARMv6, но не с ARMv5.Это обычная ситуация, с которой сталкиваются почти на всех платформах: например, если вы компилируете код C на ПК с помощью GCC, используя флаг -march=core2
, то получающийся двоичный файл может не работать на старом процессоре Pentium.
- Существует несколько соглашений о вызовах.
Соглашение о вызовах - это набор правил, которые определяют, как функции обмениваются параметрами и возвращаемыми значениями.Процессор знает только свои регистры и не имеет понятия о стеке.Соглашение о вызовах сообщает, в какие регистры идут параметры и как они кодируются (например, если есть параметр char
, он идет в младших 8 битах регистра, но вызывающий должен очистить / подписать-расширить верхний24 бита или нет?).Он описывает структуру стека и выравнивание.Он нормализует условия выравнивания и заполнения для структурных полей.
Существует два основных соглашения для ARM, которые называются ATPCS (старая) и AAPCS (новая).Они совершенно разные по вопросу значений с плавающей запятой.Для целочисленных параметров они в основном идентичны (но AAPCS требует более строгого выравнивания стека).Конечно, условные обозначения различаются в зависимости от набора инструкций и наличия большого пальца.
В некоторых случаях возможно иметь некоторый двоичный код, который соответствует как ATPCS, так и AAPCS, но это ненадежно и нет предупреждения о несоответствии.Итак, суть заключается в следующем: вы не можете иметь истинную двоичную совместимость между системами, которые используют различные соглашения о вызовах.
- Есть дополнительные сопроцессоры.
Архитектура ARMмогут быть расширены дополнительными элементами, которые добавляют свои собственные инструкции в основной набор команд.FPU является таким дополнительным сопроцессором (и он очень редко встречается на практике).Другим сопроцессором является NEON, набор инструкций SIMD, найденный на некоторых новых процессорах ARM.
Код, использующий сопроцессор, не будет работать на процессоре, который не поддерживает этот сопроцессор, если только операционная система не перехватывает соответствующие коды операцийи эмулирует сопроцессор в программном обеспечении (это более или менее то, что происходит с аргументами с плавающей запятой при использовании соглашения о вызовах ATPCS, и это медленно ).
Подводя итогЕсли у вас есть C-код, то перекомпилируйте его.Не пытайтесь повторно использовать код, скомпилированный для другой архитектуры или системы.