Как точно работает инструкция x86 LOOP?

mov ecx, 16 looptop: . . . loop looptop 

Сколько раз будет выполняться этот цикл?

Что произойдет, если ecx = 0 для начала? В этом случае происходит прыжок или провал loop ?

loop точно так же, как dec ecx / jnz , за исключением того, что он не устанавливает флаги .

Это похоже на нижнюю часть do{} while(--ecx != 0); в C. Если выполнение входит в цикл с ecx = 0 , обертка означает, что цикл будет выполняться 2 ^ 32 раза. (Или 2 ^ 64 раза в 64-битном режиме, потому что он использует RCX).

В отличие от rep movsb/stosb/etc. , он не проверяет ECX = 0 до декремента, только после.

Размер адреса определяет, использует ли он CX, ECX или RCX. Таким образом, в 64-битном коде addr32 loop похож на dec ecx / jnz , тогда как регулярный loop похож на dec rcx / jnz . Или в 16-битном коде он обычно использует CX, но префикс размера адреса ( 0x67 ) заставит его использовать ecx . Как сказано в руководстве Intel, он игнорирует REX.W, потому что он устанавливает размер операнда, а не размер адреса.

Связано: Почему циклы всегда скомпилированы так? для получения дополнительной информации о структуре цикла в asm, while(){} vs. do{}while() и как их выложить.


Дополнительные советы по отладке

Если вы когда-нибудь захотите узнать подробности инструкции, ознакомьтесь с руководством: либо официальным справочником по учебнику для учебных пособий Intel, либо справочником html с каждой записью на другой странице ( http://felixcloutier.com/x86/ ). Но учтите, что HTML не содержит интро и приложения, в которых есть подробности о том, как интерпретировать вещи, например, когда говорится, что «флаги установлены в соответствии с результатом» для инструкций, например add .

И вы можете (и должны) также просто попробовать вещи в отладчике: меняются одношаговые и наблюдательные регистры. Используйте меньшее начальное значение для ecx чтобы быстрее добраться до интересной ecx=1 . См. Также вики-файлы x86 для ссылок на руководства, руководства и советы по отладке asm внизу.


И BTW, если инструкции, которые не показаны, изменяют ecx , он может зацикливаться сколько угодно раз. Чтобы вопрос имел простой и уникальный ответ, вам нужна гарантия того, что инструкции между меткой и инструкцией loop не изменяют ecx . (Они могли бы сохранить / восстановить его, но если вы собираетесь это делать, обычно лучше просто использовать другой регистр в качестве счетчика циклов. push / pop внутри цикла делает ваш код трудным для чтения.)


Предъявляйте чрезмерное использование LOOP даже когда вам уже нужно увеличивать что-то еще в цикле. LOOP – это не единственный способ петли, и обычно это самое худшее.

Обычно вы никогда не должны использовать инструкцию цикла, если не оптимизировать размер кода за счет скорости, потому что она медленная . Компиляторы не используют его. (Так что производители процессоров не утруждают себя быстрым, поймать 22.) Используйте dec / jnz или совсем другое условие цикла. (См. Также http://agner.org/optimize/, чтобы узнать больше о том, что эффективно.)

Циклы даже не должны использовать счетчик; часто бывает так же хорошо, если не лучше сравнивать указатель с конечным адресом или проверять какое-то другое условие. (Бесцельное использование loop – одно из моих любимых мотивов, особенно когда у вас уже есть что-то в другом регистре, который работал бы как счетчик циклов.) Использование cx в качестве счетчика циклов часто просто связывает один из ваших драгоценных немногих регистров, когда вы могли бы использовал cmp / jcc в другом регистре, который вы все равно увеличивали.

IMO, loop следует рассматривать как одну из тех неясных инструкций x86, с которыми новички не должны отвлекаться. Как stosd (без префикса rep ), aam или xlatb . Тем не менее, он действительно использует их при оптимизации размера кода. (Это иногда полезно в реальной жизни для машинного кода (например, для загрузочных секторов), а не только для таких вещей, как кодовый гольф .)

ИМО, просто учите / учите, как работают условные ветви, и как создавать петли из них. Тогда вы не застрянете в мысли, что есть что-то особенное в цикле, который использует loop . Я видел SO-вопрос или комментарий, который сказал что-то вроде «Я думал, что вам нужно объявлять циклы», и не понимал, что loop – это всего лишь инструкция.

. Как я уже сказал, loop – одно из моих любимых раздражителей. Это ненавязчивая инструкция для игры в гольф, если вы не оптимизируете фактический 8086.

  • Эффективное умножение матрицы 4x4 (C vs assembly)
  • Как сделать kernel ​​для моего загрузчика?
  • Visual Studio 2010 не создает перед запуском при изменении кода
  • использование ILMerge с библиотеками .NET 4
  • Дополнительная информация о макете памяти исполняемой программы (процесса)
  • Как извлечь сборку из GAC?
  • Возможно ли одноуровневое многоязычное развертывание Windows Forms (ILMerge и спутниковые сборки / локализация)?
  • Как загрузить сборку во время выполнения перед событием AssemblyResolve?
  • Размер сборки .NET влияет на производительность?
  • Как вы прокручиваете загруженные в настоящее время сборки?
  • Как загрузить сборку .NET для операций отражения и впоследствии выгрузить ее?
  • Interesting Posts

    Простая командная строка для загрузки удаленного артефакта maven2 в локальный repository?

    Сделать дочерний элемент видимым вне переполнения: скрытый родитель

    Как сделать Firefox для проверки орфографии на нескольких языках одновременно?

    Подключение к SonicWall VPN с Linux-машины

    Вывод первого аргумента шаблона с другими параметрами шаблона по умолчанию

    Улучшить производительность SQLite в секунду в секунду?

    Как применить шаблон обогащения my-library к коллекциям Scala?

    Как разрешить трафик VPN только при подключении к незащищенной беспроводной точке доступа?

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

    Windows 8: не удается получить доступ к внешним дискам. «Местоположение недоступно» «Доступ запрещен»

    Outlook 2007: ответ и пересылка не используются для форматирования по умолчанию

    Как я могу исправить / восстановить поврежденный файл PDF?

    Java: разделите строку, когда найдена заглавная буква

    Гиперссылка фрагмента текста в Excel

    Как читать текстовый файл в Android?

    Давайте будем гением компьютера.