Использование суффикса.W в ассемблере ARM
Я читаю Руководство по набору инструкций и задаюсь вопросом о .W
суффикс.
В руководстве сказано:
В некоторых случаях может потребоваться указать суффикс.W, например, если операнд является меткой инструкции или литеральных данных, как в случае инструкций ветвления. Это потому, что ассемблер не может автоматически генерировать кодировку правильного размера.
Я не могу придумать причину, по которой мне нужно переопределить кодировку ассемблера по умолчанию. То, что я пробовал до сих пор, всегда прекрасно компилируется без .W
,
Действительно ли они добавили специальный синтаксис для преодоления возможной ошибки в ассемблере (может быть, пока что исправлено)?
Можете ли вы привести пример, где я должен явно использовать.W (Thumb2 на Cortex-M3).
1 ответ
.W
Суффикс все еще необходим в синтаксисе, даже если большинство людей никогда не будут использовать его явно, чтобы поддерживать поведение, при котором дизассемблирование любого допустимого кода и передача полученного источника обратно через ассемблер приводит к точно таким же инструкциям снова. Таким образом, каждая правильная кодировка команд должна иметь определенный способ однозначного представления на языке, даже если он не является предпочтительным, который ассемблер выберет по умолчанию для базовых мнемоник и операндов. И, конечно, поскольку он существует в синтаксисе, вам не нужно писать машинный код напрямую или исправлять двоичные файлы, чтобы получить эти кодировки в первую очередь.
Теперь, существуют различные эзотерические причины для того, чтобы желать не предпочтительного кодирования в конечном двоичном коде - такие как настройка выравнивания команд, использование кода в качестве данных и т. Д. - но наименее безумным, вероятно, является перемещение. Если у вас есть ветвь к внешнему символу или символ в другом разделе, ассемблер не обязательно знает, как далеко этот символ окажется в конце. Поэтому ему приходится выбирать между испусканием узкой команды, которая может закончиться несвязываемой, или широкой командой, которая может закончиться потерей кодового пространства, если цель окажется достаточно близко. Кажется, что и GNU as, и armasm подходят для последнего, хотя не так сложно представить какой-то специализированный встроенный ассемблер, по умолчанию использующий первый по размеру.
Перемещение во время выполнения является еще более сильным аргументом: у вас есть ветвь или литеральная загрузка, которая разрешается во время сборки, но вы можете хотеть при определенных обстоятельствах хот-патч нацелиться на что-то другое. Это может потребовать дополнительного диапазона широкого кодирования, даже если исходная цель находится в пределах диапазона узкого.