При изучении программирования на языке Ассамблеи я натолкнулся на термины «Псевдо-op» и «Machin-op». Я не уверен, какова их функциональность и как они отличаются друг от друга?Разница между Pseudo-op и Machine-op?
ответ
Помимо ассемблерных директив, для архитектур RISC обычно существуют псевдооператоры, которые расширяются до нескольких инструкций.
Наиболее распространенным типом является псевдо-операция для последовательности инструкций, необходимых для получения 32-разрядной константы (например, адреса) в регистр. Поскольку фиксированная 32-битная команда не имеет места для произвольного 32-битного немедленного, машина не может сделать это в одной инструкции. Тем не менее, обычно нет ничего, что можно было бы разделить на пару инструкций с 16-битными операциями, было бы неприятно делать это вручную. (IIRC, некоторые суперскалярные процессоры в порядке распознают такие пары, когда они выполняются параллельно друг другу, все еще запуская их параллельно, даже если они изменяют один и тот же регистр.) Псевдо-инструкции ассемблера ARM MOV32
и ADRL
делают это.
Другим интересным примером является ARM ldr r0, =0x12345678
. Он всегда собирает одну команду, но может выбирать из двух стратегий: если константу можно представить как немедленную (using ARM's barrel shifter), ассемблер использует MOV. Если нет, он помещает константу в ближайший литеральный пул и использует относительную нагрузку на ПК. Таким образом, этот псевдооператор может выдать команду и данных (все же в том же разделе, я думаю).
(Непрозрачная форма инструкции LDR является обычной формой регистра нагрузки, поддерживающей различные режимы адресации ARM, например ldr r0, [r1, r3, lsl #2]
для загрузки от r1 + r3 <<2
). Так же, мнемонические может быть псевдо-оп или машинная в зависимости от операндов
MIPS принимает псевдо-инструкции к экстремальным, с нормальным ABI резервирования по меньшей мере, один из 32 архитектурных регистров для использования как временный псевдо-ops-сгенерированный ассемблером! (Я думаю, разработчики MIPS считали, что 32 действительно больше, чем нужно, потому что в стандартном ABI нормально для обработчиков прерываний асинхронно clobber 2 других регистра, что делает их небезопасными для использования кодом пользователя. Я предполагаю, что это упрощает дизайн vs . с аппаратной поддержкой больше в сохранении/восстановлении архитектурного состояния на прерываниях, но я не смотрел подробности.)
Nitpick: Эта 'LDR 'form генерирует только одну команду, в этом случае размещение 32-битной константы в литеральном пуле, рядом с которым затем может быть проиндексирована из нагрузки. Однако 'MOV32' и' ADRL' делают кусочки констант из нескольких инструкций. – doynax
@doynax: hrm, я думал, что LDR может выбирать разные стратегии. Это просто, что он может выбрать MOV, если константа вписывается в одно мгновение? –
Правильно, он может выбрать немедленную команду «MOV» с одной инструкцией, тогда как «ADRL» и «MOV32» всегда арифметически вычисляют адрес в двух инструкциях. По крайней мере, это то, что я сделал ассемблером IAR ARM в последний раз, когда я проверил. «ADRL» особенно любопытно, поскольку он поддерживает только выражения времени сборки, но все же создает манекены для коротких расстояний. Скорее всего, немедленный псевдооператор был бы полезен, но, возможно, было бы безопаснее дать ясному контролю программиста, что со случайными побочными эффектами флага на Thumb и тому подобное. – doynax
Машинные операции обычно являются инструкциями по сборке, которые генерируют конкретный машинный код. Pseudo-ops не обязательно генерируют машинный код. Часто псевдооператоры также называются ассемблерными директивами, и в качестве примера это директивы в _GCC_: https://sourceware.org/binutils/docs/as/Pseudo-Ops.html#Pseudo-Ops –