Как использовать инструкцию MOV в ARM с непосредственным числом как второй операнд

Я только начинаю изучать ассемблер ARM и не соглашаюсь, как использовать MOV для передачи непосредственного числа в регистр.

И из справочника ARM и из моего учебника, сказано, что диапазон непосредственного числа после инструкции MOV 0-255. Но когда я тестирую на своем собственном ПК в ADS 1.2 IDE, инструкции

MOV     R2, #0xFFFFFFFF

работает хорошо. Разве номер 0xFFFFFFFF из диапазона согласно спецификации не?

Надежда кто-то может дать мне руку.

С уважением.

16
задан starblue 13 April 2010 в 06:38
поделиться

4 ответа

Помните, что ARM может выполнять определенный набор манипуляций с непосредственным значением как часть бочкообразного шифтера, который встроен в опкоды ARM.

Эта небольшая статья содержит одно из самых ясных объяснений некоторых трюков, которые ассемблер ARM может использовать, чтобы вместить большое непосредственное число в небольшое доступное пространство инструкции ARM:

В статье обсуждается трюк, вероятно, использованный в вашем конкретном примере генерации опкода MVN для загрузки побитового дополнения непосредственного значения.

Такие манипуляции можно проводить не со всеми непосредственными значениями, но ассемблеры ARM предположительно довольно умны в этом отношении (и компиляторы C, конечно, тоже). Если не удается выполнить трюки со сдвигом/комплиментом, значение обычно загружается из относительного местоположения PC или, возможно, путем "наращивания" значения из нескольких инструкций.

13
ответ дан 30 November 2019 в 21:10
поделиться

Одна из возможностей состоит в том, что ассемблер ARM отбрасывает значащие биты числа и использует только самый младший FF.

Команда MOV является неотъемлемой частью многих наборов команд ЦП, и обычно ассемблер определяет размер целевого регистра и непосредственно передаваемое значение.

Например, следующие инструкции MOV из набора x86:

MOV BL, 80h, ; 8bit
MOV BX, ACACh ;16bit
MOV EBX, 12123434h ; 32bit
-2
ответ дан 30 November 2019 в 21:10
поделиться

Возможно, вы видите артефакты от знакового расширения исходного значения. Если инструменты, которые вы используете для просмотра разборки, обрабатывают 0..255 как подписанный байт, то при загрузке его в больший тип int (или регистр) он заполнит все верхние биты знаковым битом оригинала. ценить. Или, другими словами, если 0xFF - байт со знаком, его десятичное значение равно -1. Поместите это в 32-битный регистр, и шестнадцатеричное значение будет выглядеть как 0xFFFFFFFF, а его десятичное значение по-прежнему равно -1.

Попробуйте использовать значение без установленного старшего бита, например 0x7F. Поскольку знаковый бит не установлен, я предполагаю, что он заполнит старшие биты нулями при загрузке в регистр или поле большего типа int.

Также возможно, что компилятор / ассемблер усекает любое указанное вами значение. Я бы счел это ошибкой исходного кода, но ассемблеры - забавные твари. Если указать 0x7FF, компилируется ли он в 0x7FF (без усечения и больше 0..255) или в 0xFFFFFFFF (с усечением до 0..255, байт со знаком)?

1
ответ дан 30 November 2019 в 21:10
поделиться

Одиночная инструкция ARM может кодировать только непосредственную константу, которая может быть представлена ​​как 8-битовое непосредственное значение, сдвинутое на любую даже степень двойки.

Однако есть также инструкция MVN , которая похожа на MOV , но инвертирует все биты. Таким образом, хотя MOV R2, # 0xFFFFFFFF не может быть закодирован как инструкция MOV , он может быть закодирован как MVN R2, # 0 . Ассемблер вполне может выполнить это преобразование за вас.

12
ответ дан 30 November 2019 в 21:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: