Что означает инструкция 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 сохраняет это историческое наследие в нотации.