Как регистры процессора сохраняют свои значения между задачами?

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


Ответы (3 шт):

Автор решения: Stas_ Zima

Регистр — минимальная ячейка памяти данных. Регистры состоят из триггеров (англ. latches/flip-flops). Триггеры, в свою очередь, состоят из логических элементов и могут хранить в себе 1 бит информации.

Прим. перев. Триггеры могут быть синхронные и асинхронные. Асинхронные могут менять своё состояние в любой момент, а синхронные только во время положительного/отрицательного перепада на входе синхронизации.

По функциональному назначению триггеры делятся на несколько групп:

RS-триггер: сохраняет своё состояние при нулевых уровнях на обоих входах и изменяет его при установке единице на одном из входов (Reset/Set — Сброс/Установка). JK-триггер: идентичен RS-триггеру за исключением того, что при подаче единиц сразу на два входа триггер меняет своё состояние на противоположное (счётный режим). T-триггер: меняет своё состояние на противоположное при каждом такте на его единственном входе. D-триггер: запоминает состояние на входе в момент синхронизации. Асинхронные D-триггеры смысла не имеют. Для хранения промежуточных данных ОЗУ не подходит, т. к. это замедлит работу процессора. Промежуточные данные отсылаются в регистры по шине. В них могут храниться команды, выходные данные и даже адреса ячеек памяти.

→ Ссылка
Автор решения: nick_n_a

Регистры процессора в "неактивное" время хранятся в TSS контексте задачи. Параллельная задача может получить доступ к регистрам другой задачи обрабатывая байты просто как память.

Эти данные хранятся в том же месте где GDT LDT дескрипторы. Отдельно ТSS можно почитать. GDT - это корень таблицы, один из элементов которой может быть TSS. Хранятся структуры в оперативной памяти. Если хватает прав доступа - то можно править их прямо в памяти.

Под виндой доступ к регистрам можно получить функцией SetThreadContext GetThreadContext. Структура CONTEXT виндовая частично повторяет структуру TSS. Что бы подменить значение регистров задачу нужно приостановить. При переключении на задачу определенное к-во тактов ЦП уходит на чтение регистров из памяти ТSS в сверхбыструю память регистров (а при приостановке задачи чтение назад). ЦП это делает сам, без вмешательств со стороны. Единственное что можно самому сделать - это сказать - срочно бери вот эту TSS выполнять, или можно стопнуть задачу. Также можно можно сказать чтобы не все регистры хранил (например не хранил mmx или sse группу регистров).

Если хотите под современные процессоры - то можно скачать мануалы на процессор на сайте http://intel.com или на сайте AMD. Там есть описание и под x86 и под x64 режим. Если для общего ознакомления - то любое где 386 и TSS например как ниже

Ссылки

→ Ссылка
Автор решения: PRODIGY

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

Здесь нужно вспомнить базовые основы..

  1. Все процессы/действия в системе должны протекать синхронно, поэтому напрямую зависят от точности хода таймеров. Для часов достаточно милли/сек 0.000 и их обслуживает древний таймер PIT/RTC (Real-Time-Clock). Но для остальных процессов это крупная единица, и требуется более точный таймер с разрешением в микро/сек 0.000000, и нано/сек 0.000000000. С такой скважностью работает таймер ACPI (хотя способен и PIT), но в системе имеется и более точный современный таймер HPET (High-Precision-Event-Timer), который нужно включить в биосе. Включение HPET наводит порядок в системе, устраняя "траекторию пьяного гонщика".

  2. В ОС может быть запущено более 1000 исполняемых потоков и чтобы имитировать многозадачность, системный планировщик чередует их исполнение, выделяя каждому свой "квант" времени. По умолчанию в Win один квант равен 15 нано/сек, по истечению которых управление передаётся сл.исполняемому потоку - такой алго действует всегда! Более того в ОС имеется "система приоритетов" 0-15, благодаря которой, например, системный "диспетчер задач" может выгружать зависшие потоки. Потоки с обычным приоритетом (наши) не получат управления, пока работает поток с более высоким приоритетом. Узнать приоритет своего/чужого процесса можно в диспетчере-задач, правой кнопкой мыши.

  3. В системе имеется глобальная таблица GDT, в которой описывается и "сегмент состояния задачи/процесса" TSS. Каждое ядро процессора имеет свою таблицу GDT, и соответственно свой сегмент памяти TSS. Ядро CPU, на котором будет исполняться процесс, назначается системой при его старте и называется "Affinity Mask" - эта инфа хранится в структуре-паспорта процесса EPROCESS. Таким образом, когда планировщик переключает потоки, состояние их регистров сбрасывается в строго сегмент TSS того ядра, на котором работал этот поток, а не в TSS соседнего ядра - иначе невозможно будет вести учёт.

→ Ссылка