Что означает инструкция x86-64 "shrb %dil"?

Я знаю это shrb обозначает логическое смещение вправо. Обычно это используется с двумя аргументами, shrb amount, %register, Тем не менее, в коде, который я смотрю, он не использует величину сдвига - там указан только регистр:

shrb %dil

где %dil обозначает младший младший байт %rdi,

Теперь указанная выше команда подразумевает, что мы сдвигаемся вправо на 1? Как бы вы узнали об этом? Есть ли способ как-то выполнить команду и посмотреть, что получится? Документация не помогла предоставить информацию о том, что происходит, когда пропускается сумма смены: https://docs.oracle.com/cd/E19253-01/817-5477/817-5477.pdf

1 ответ

Это синтаксис AT&T/GAS, который сильно отличается от синтаксиса Intel. В синтаксисе Intel эквивалентная инструкция будет:

shr  dil, 1

Это 64-битный код режима, который сдвигает младшие 8 бит edi зарегистрироваться (относится к использованию dil мнемоника) прямо на 1 бит. Младший значащий бит (операнда назначения) сдвигается во флаг переноса (CF), и самый значимый бит очищается. (Стандартное поведение для shr.)

Обратите внимание, что в вашем коде shr мнемоника с суффиксом b, Это указывает на то, что это bоперация размером с вас. Принимая во внимание, что синтаксис Intel использует аннотации к одному из операндов (например, DWORD PTR) для устранения неоднозначности синтаксис AT & T использует суффиксы команд: b для байта, w к слову, l для длинного слова, q для четырех слов и т. д.

В этом случае b суффикс на самом деле является необязательным, даже в синтаксисе AT & T, поскольку операнд-адресат, являющийся 8-битным регистром, делает инструкцию однозначной. Однако инструменты Gnu, как правило, добавляют суффиксы ко всем инструкциям для согласованности, даже если нет никакой двусмысленности. Это, вероятно, где код, из которого вы пришли.

Кроме того, в синтаксисе AT & T shr, sar, а также shl инструкции часто опускают величину сдвига, когда она равна 1. Другими словами, было бы технически правильно записать это как:

shrb  $1, %dil

но большинство инструментов, которые я видел, не будут использовать эту форму, особенно дизассемблеры Gnu. (Обратите внимание на другое различие между синтаксисом AT & T и Intel: операнды назначения и источника меняются местами.)

Пропуск суммы смены, когда она равна 1, может быть по историческим причинам. На самом деле существует три разных кодировки для каждой из команд сдвига на x86: одна, которая сдвигается на постоянную 1, другая, которая сдвигается мгновенно, и другая, которая сдвигается на содержимое cl регистр. Кодирование с непосредственным сдвигом не было введено до 286 года, поэтому существует отдельное (более короткое) кодирование для сдвига на 1. В настоящее время вы можете кодировать shift-by-1 как shift-by-немедленный-1, но ни один здравомыслящий ассемблер не сделает этого. Тем не менее, синтаксис AT&T/GAS сохраняет это историческое наследие в нотации.

Другие вопросы по тегам