Прерывание инструкции по сборке во время работы - PullRequest
4 голосов
/ 15 марта 2019

Когда прерывание поступает в ЦП, оно обрабатывается путем сохранения текущего местоположения адреса до перехода в обработчик, если оно подтверждено.В противном случае оно игнорируется.

Интересно, прерывается ли вызов инструкции по сборке.

Например,

mvi a, 03h ; put 3 value into acc. in 8080 assembly

Может ли быть прервана однострочная инструкция?Или, если нет, он атомарный ??

Всегда ли гарантируется, что «инструкция по сборке в одну строку» всегда атомарна?

Что если нет ключевого слова «lock», т. Е. В 8080сборка, тогда как обеспечивается атомарность?

Например, что, если требуется работать с 64-битной суммой, но нет способа сделать это с помощью «однострочной инструкции», и при работе на ней возникает прерываниесумма.Как это можно предотвратить на уровне сборки ??

Концепция для меня начинает сводиться.

Ответы [ 2 ]

3 голосов
/ 15 марта 2019

Я не уверен, что 8080 был разработан для использования в многопроцессорных системах с общей оперативной памятью, что, однако, не обязательно означает невозможность или отсутствие таких систем. Префикс блокировки 8086 предназначен для таких систем, чтобы гарантировать, что только один ЦП может иметь эксклюзивный доступ к памяти при выполнении последовательности чтения из памяти, изменения значения, записи в память (RMW). Префикс блокировки не предназначен для защиты команды или нескольких инструкций от прерывания обработчиком прерываний.

Вы можете быть уверены, что отдельные инструкции не прерываются в полете. Либо им разрешают работать до завершения, либо любые их побочные эффекты отменяются, и они перезапускаются позднее. Это распространенная реализация на большинстве процессоров. Без этого было бы сложно написать код с хорошим поведением при наличии прерываний.

Действительно, вы не можете выполнить 64-битное сложение с одной инструкцией 8080, поэтому ISR может прервать эту операцию.

Если вы вообще не хотите этого прерывания, вы можете защитить свое 64-битное добавление отключением прерываний и инструкциями включения (DI и EI).

Если вы хотите, чтобы ISR выгружал 64-битные, но не нарушал регистры, которые использует 64-битное добавление, ISR должен сохранять и восстанавливать эти регистры, например, используя инструкции PUSH и POP.

Найдите руководство по 8080 для подробного описания обработки прерываний (например, здесь ).

2 голосов
/ 15 марта 2019

Да, все "нормальные" ISA, включая 8080 и x86, гарантируют, что инструкции являются атомарными по отношению к прерываниям на одном ядре. Либо инструкция полностью выполнена, и все ее архитектурные эффекты видны (в прерывании обработчик), или ни один из них не является. Любые отклонения от этого правила, как правило, тщательно документируются.


Например, Руководство Intel по архитектуре x86, том 3 (~ 1000 страниц в формате PDF) имеет смысл особо сказать следующее:

6.6 ПЕРЕЗАГРУЗКА ПРОГРАММЫ ИЛИ ЗАДАЧИ
Чтобы разрешить перезапуск программы или задачи после обработки исключения или прерывания, все исключения (кроме прерываний) гарантированно сообщать об исключениях на границе инструкции. Все прерывания гарантированно будут взят на границе инструкции.

В старом абзаце руководства Intel по vol.1 говорится об одноядерных системах, использующих cmpxchg без a lock префикса для атомарного чтения-изменения-записи (в отношении к другому программному обеспечению, а не к аппаратному доступу DMA).

Инструкция CMPXCHG обычно используется для тестирования и модификации семафоров. Он проверяет, является ли семафор это бесплатно. Если семафор свободен, он помечается как выделенный; в противном случае он получает идентификатор текущего владельца. Это все сделано за одну непрерывную операцию . [потому что это одна инструкция] В однопроцессорной системе инструкция CMPXCHG устраняет необходимость переключитесь на уровень защиты 0 (чтобы отключить прерывания) перед выполнением нескольких инструкций для проверки и изменения семафора.

Для многопроцессорных систем CMPXCHG можно комбинировать с префиксом LOCK для выполнения сравнения и обменная операция атомарно. (См. «Заблокированные атомарные операции» в главе 8 «Управление несколькими процессорами»). Руководства разработчика программного обеспечения Intel® 64 и IA-32, том 3A, для получения дополнительной информации об атомных операции.)

(Подробнее о префиксе lock и о его реализации по сравнению с неблокированным add [mem], 1 см. Может ли num ++ быть атомарным для 'int num'? )

Как указывает Intel в этом первом абзаце, один из способов достижения атомарности в нескольких командах - отключить прерывания, а затем снова включить, когда вы закончите. Это лучше, чем использование мьютекса для защиты большее целое число, особенно если вы говорите о данных, которыми обмениваются основная программа и обработчик прерываний. Если прерывание происходит, когда основная программа удерживает блокировку, она не может ждать , пока блокировка не будет снята; этого никогда не произойдет.

Отключение прерываний обычно довольно дешево для простых конвейеров, особенно микроконтроллеров. (Иногда вам нужно сохранить предыдущее состояние прерывания вместо того, чтобы безоговорочно разрешать прерывания. Например, функция, которая может быть вызвана с уже отключенными прерываниями.)

В любом случае, отключение прерываний - это то, как вы можете атомарно что-то делать с 64-разрядным целым числом на 8080.


Несколько длительных инструкций являются прерываемыми в соответствии с правилами, задокументированными для этой инструкции.

например. rep -строковые инструкции x86, такие как rep movsb (memcpy одной инструкции произвольного размера), архитектурно эквивалентны повторению базовой инструкции (movsb) RCX раз, уменьшению RCX каждый раз и увеличению или уменьшению входов указателя (RSI) и RDI). Прерывание, прибывающее во время копирования, может установить RCX «начальное_значение - byte_copied , so on resuming after the interrupt the rep movsb` будет запущен снова и сделает оставшуюся часть копии.

К другим примерам x86 относятся сборочные нагрузки SIMD (AVX2 / AVX512) и хранилища разброса (AVX512). например vpgatherdd ymm0, [rdi + ymm1*4], ymm2 выполняет до 8 32-битных нагрузок, в соответствии с которыми установлены элементы ymm2. И результаты объединены в ymm0.

В гоВ обычном случае (без прерываний, сбоев страниц или других синхронных исключений во время сбора) вы получаете данные в регистре назначения, и регистр маски обнуляется. Таким образом, регистр маски дает центральному процессору место для сохранения прогресса.

Сбор и разбрасывание выполняются медленно, и может потребоваться запуск нескольких сбоев страниц, поэтому для синхронных исключений это гарантирует продвижение вперед даже при патологических условиях, когда обработка сбоя страницы не отображает все остальные страницы. Но, что более важно, это означает, что нужно избегать повторных пропусков TLB, если страница среднего элемента дает сбой, и не отбрасывать работу, если приходит асинхронное прерывание.


Некоторые другие длительные инструкции (например, wbinvd, которые сбрасывают все кэши данных на всех ядрах) не являются архитектурно прерываемыми или даже микро архитектурно не могут быть отменены (чтобы отказаться от частичной работы и иди обрабатывать прерывание). Он привилегирован, поэтому пользовательское пространство не может выполнить его как атаку типа «отказ в обслуживании», вызывающую высокую задержку прерывания.


связанный пример документирования забавного поведения - это когда x86 popad выходит за пределы стека (предел сегмента). Это исключение (не внешнее прерывание), задокументированное ранее в руководстве по vol.3, в разделе 6.5 КЛАССИФИКАЦИИ ИСКЛЮЧЕНИЙ (то есть неисправность / прерывание / прерывание, см. PDF-файл для более подробной информации.)

Примечание
Одно подмножество исключений, обычно сообщаемое как ошибка, не перезапускается Такие исключения приводят к потере некоторого состояния процессора. Например, выполняет команду POPAD , где находится кадр стека пересечение конца сегмента стека вызывает сообщение об ошибке. В этой ситуации Обработчик исключений видит, что указатель команд (CS: EIP) был восстановлен, как если бы POPAD Инструкция не была выполнена. Однако состояние внутреннего процессора (общего назначения регистры) будут изменены. Такие случаи считаются ошибками программирования. Приложение вызывающий этот класс исключений должен быть прерван операционной системой.

Обратите внимание, что это только в том случае, если popad само по себе вызывает исключение, не по любой другой причине. Внешнее прерывание не может разделить popad так, как это возможно для rep movsb или vpgatherdd

(Я полагаю, что в случае сбоя popad он эффективно работает итеративно, извлекая 1 регистр за раз и логически модифицируя RSP / ESP / SP, а также целевой регистр. Вместо проверки всего региона он собирается загрузка предела сегмента перед запуском, потому что это потребует дополнительного добавления, я думаю.)


Процессоры, вышедшие из строя, возвращаются к прерыванию из-за прерываний.

Процессоры, такие как современный x86 с нестандартным выполнением и разделением сложных команд на несколько мопов, по-прежнему гарантируют, что это так. Когда приходит прерывание, ЦПУ должен выбрать точку между двумя инструкциями, которые он находится в середине выполнения, как место, где архитектурно происходит прерывание. Он должен отказаться от любой работы, которая уже проделана для декодирования или начала выполнения любых последующих инструкций. Если предположить, что прерывания возвращаются, они будут переизбраны и снова начнут выполняться.

См. Когда происходит прерывание, что происходит с инструкциями в конвейере? .

Как говорит Энди Глеу, современные процессоры не переименовывают уровень привилегий, поэтому то, что логически должно произойти (отбрасывая более поздние инструкции из конвейера), соответствует тому, что на самом деле происходит. Интересный факт: прерывания x86 не полностью сериализуются. Это означает, что у них нет для очистки буфера хранилища, а также для опустошения буфера ReOrder выполнения вне очереди. Они возвращают серверную часть OoO обратно в состояние вывода из эксплуатации (поскольку он не переименовывает уровень привилегий, поэтому он не может безопасно обрабатывать одновременное выполнение пользовательских и ядерных операций в полете), но обработчик прерываний может потенциально начать выполняться до того, как Буфер хранилища передал все ожидающие хранилища на L1d.

(Хранить данные из вышедших из употребления инструкций хранилища не спекулятивно; это определенно произойдет, и ЦП уже сбросил состояние, к которому необходимо иметь возможность откатиться до этой инструкции хранилища. Таким образом, большой буфер хранилища полон разбросанных Запасы кэша могут привести к задержке прерывания.)

...