User Tag List

Показано с 41 по 50 из 133

Тема: Ядро с 32 битами и виртуализацией

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #10

    Регистрация
    25.11.2015
    Адрес
    г. Москва
    Сообщений
    192
    Спасибо Благодарностей отдано 
    12
    Спасибо Благодарностей получено 
    16
    Поблагодарили
    14 сообщений
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Bolt Посмотреть сообщение
    Вариант четвёртый, с регистрами. Лишних тактов на djnz не тратится, но тут я вообще не понимаю как это реализовать. Нет, если тупо гнать данные, сравнивая PC и перепрыгивая на другой адрес, то всё просто. Но что делать с прерываниями внутри цикла? Какой адрес возврата сохранять в стек? Какое значение читать из регистра-счётчика (оно будет меньше, чем должно быть для текущей выполняемой инструкции)? Как перегружать поток при выходе из цикла?
    В самом простом для понимания варианте есть:
    Код:
    	DoLoop LoopEnd, LoopCnt
    LoopStart: - реально не требуется так как команда запуска цикла может вычислить эту метку сама
    	...	
    	LastInst
    LoopEnd: - метка первой команды за циклом(для простоты понимания)
    Инструкция запуска цикла адрес следующий инструкции записывает в LoopStat, а в LoopEnd и LoopCnt пишет переданные в параметрах значения. Когда PC становится равным LoopEnd мы уменьшаем счётчик и если еще не 0, то перезаписываем PC из LoopStart, иначе продолжаем выполнять код как обычно. Проблема здесь только в том, что мы либо теряем такт на перезапись PC, либо снижаем скорость выборки программы чтобы успело установиться новое значение PC при выдаче его на шину. Именно по-этому метку нужно перенести на последнюю инструкцию, тогда компаратор PC c LoopEnd скажет нужно ли заменить его на LoopStart (при условии что счётчик не 0).

    Реально действия последней команды ничем не отличаются от остальных, за исключением того, что к ним добавляется уменьшение счётчика и выбор что записывать в PC. То есть, если переход в прерывание выполняется перед последней командой цикла, в стек пойдёт её адрес. Если после, то сохраняется адрес первой команды за циклом, если счётчик как раз обнулился, иначе сохраняется LoopStart. Ни эти регистры на прерывание, ни прерывание на регистры никак не влияют, поскольку нужно вернуться из прерывания и дойти до LoopEnd, чтобы этот механизм снова сработал. Если последней командой цикла стоит вызов подпрограммы, мы должны сохранить в стек либо адрес после цикла, либо LoopStart. Из такого цикла можно делать условные переходы, главное потом вернуться обратно внутрь.

    Если мы хотим запустить вложенный цикл, то нам требуется сохранить LoopStart, LoopEnd и LoopCnt, а после его окончания восстановить. Или можно поручить это команде которая запускает цикл, а восстановление будет производиться при обнулении счётчика. Хотя для ситуации когда цикл не вложенный, и перед запуском счётчик и так был 0 это будет лишней работой. Может, есть смысл сделать два вида команды запуска цикла с сохранением предыдущего и без, правда тогда еще появится аппаратный флаг, чтобы указать на необходимость восстановления в конце счётчиков внешнего цикла.

    Соображение по поводу конвейера и обработки прерываний: сигнал запроса прерываний должен просто заблокировать выборку следующей инструкции, заморозить PC, запретить прерывания и подсунуть в регистр инструкций команду перехода к обработчику, достаточно обычного CALL и на этом его миссия может быть завершена. Тогда вызов прерываний пойдёт по конвейеру вместе с обычными командами.
    Последний раз редактировалось blackmirror; 31.01.2020 в 20:41.

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Ответов: 465
    Последнее: 03.01.2020, 07:15
  2. Ответов: 16
    Последнее: 02.08.2005, 12:20

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •