Префикс x86 rep с нулевым счетчиком: что происходит?

Что произойдет, если начальный счетчик префикса x86 rep будет равен нулю?

В руководстве Intel прямо говорится, что это while count != 0 цикл с тестом наверху, что является разумным ожидаемым поведением.

Но большинство расплывчатых отчетов, которые я видел в других местах, предполагают, что нет никакого начального теста на ноль, поэтому это будет похоже на обратный отсчет с тестом в конце, и поэтому катастрофа, если это repeat{… count —=1; }until count == 0; или кто знает.

Я добавил явную условную ветку вверху и хотел бы удалить ее, если смогу.

Cecil Ward 01.06.2023 07:39

У z80 не было начального теста для своих строковых инструкций, может быть, вы слышали это в этом контексте?

harold 01.06.2023 11:08

Я старый профессиональный программист Z80 на ассемблере. Так что, возможно, страх остался в моем сердце.

Cecil Ward 01.06.2023 18:15
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При RCX=0 ничего не происходит; rep префиксы сначала проверяют наличие нуля, как говорит псевдокод. (В отличие от инструкции loop, которая точно такая же, как нижняя часть do{}while(--ecx) или dec rcx/jnz, но не влияет на ФЛАГИ.)

Я думаю, что слышал, что это редко используется в качестве идиомы для условной загрузки или сохранения с rep lodsw или rep stosw со счетом 0 или 1, особенно в старые добрые времена до cmov. (cmov — это безусловная загрузка, подающая операцию выбора ALU, поэтому ей нужен допустимый адрес, в отличие от rep lods с нулевым счетчиком.) Это неэффективно, особенно для rep stos на современном x86 с микрокодом Fast Strings (P6 и выше), особенно без что-нибудь вроде Fast Short Rep-Moves (Ice Lake IIRC.)

То же самое относится к инструкциям, которые обрабатывают префиксы как repz / repnz (cmps/scas) вместо безусловного rep (lods/stos/movs). Выполнение нулевых итераций означает, что они оставляют FLAGS немодифицированными.

Если вы хотите проверить FLAGS после repe/ne cmps/scas, вам нужно убедиться, что счетчик не равен нулю, или что FLAGS уже установлен таким образом, что вы будете выполнять полезный переход для буферов нулевой длины. (Возможно, из-за xor-обнуления регистра, который вам понадобится позже.)


rep movs и rep stos имеют микрокод быстрых строк на ЦП, начиная с P6, но накладные расходы при запуске делают их редкостными, особенно когда размеры могут быть короткими и/или данные могут быть смещены. Они более полезны в коде ядра, где вы не можете свободно использовать регистры XMM. Некоторые последние процессоры, такие как Ice Lake, имеют микрокод fast-short-rep, который, я думаю, должен уменьшить накладные расходы при запуске для небольших количеств.

repe/ne scas/cmps не имеют микрокода быстрых строк на большинстве процессоров, только на самых последних процессорах, таких как Sapphire Rapids и, возможно, на P-ядрах Alder Lake. Таким образом, они довольно медленные, например, одна загрузка за такт (то есть 2 цикла за счет для cmpsb/w/d/q), согласно тестированию https://agner.org/optimize/ и https://uops.info/.

repe и repne оба работают одинаково, если счетчик изначально равен нулю, то повторные инструкции пропускаются без какого-либо эффекта. Важно отметить, что флаги не изменяются инструкцией cmps или scas, пропущенной таким образом. Поэтому, если вы хотите перейти, например, к нулевому флагу, вы должны убедиться, что счетчик изначально никогда не равен нулю, или что нулевой флаг предварительно инициализирован так, как вы хотите, например, в hg.pushbx.org/ecm. /ldebug/file/eb3730a8118e/источник/…
ecm 01.06.2023 08:17

@ecm: Спасибо, я думаю, что возможная ошибка без изменений FLAGS была тем, что я пытался запомнить как «особое» в нулевом счете для rep[n]e cmps/scas. Обновлять.

Peter Cordes 01.06.2023 16:25

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