понедельник, 29 июня 2015 г.

Системные вещи. Ответы Часть 1.

Введение

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

Я запишу лишь некоторый минимум, который мы хотели бы услышать от кандидата по каждому вопросу.

Что такое архитектура процессора?

Архитектура процессора — количественная составляющая компонентов процессора компьютера (например, регистры процессора).
С точки зрения программиста — совместимость с определённым набором команд (например, процессоры, совместимые с командами Intel х86), структуры команд и способ исполнения.
С точки зрения аппаратной составляющей вычислительной системы — это некий набор свойств и качеств, присущий целому семейству процессоров (например, RISC и CISC).

Здесь кандидат может получить жирный плюс в карму, если сможет рассказать про Arm и какие-то ее особенности. Не могу сказать, что мы активно используем эту архитектуру, но все же это будет отмечено на собеседовании. Ведь если кандидат смог разобраться в этой архитектуре самостоятельно, скорее всего сможет разобраться и в других сложных вопросах. Рассказ про особенности CISC и RISC так же будет большим плюсом.

Чем x86 отличается от x64?

Большинство кандидатов при ответе на этот вопрос начинают рассказывать о том, что в x86 компьютере нельзя использовать больше 3.5 Гб оперативной памяти. В этом случае мы сразу упоминаем про PAE и просим освятить этот вопрос поподробнее. К сожалению, пока ни один кандидат не смог ничего нам рассказать. На самом деле компьютеры вполне успешно использовали больше 3.5 Гб оперативной памяти и без новой архитектуры, а различий куда больше:
  1. Размер регистров процессора. Очевидно, что в x64 размер регистров общего назначения, арифметических и логических операций над целыми числами и виртуальных адресов стал равен 64-битам.
  2. Количество регистров процессора. 
  3. Новый режим работы Long mode.
Есть так же несколько отличий для программиста:
  1. Размер виртуального адресного пространства увеличился с 3.5 Гб до 20Гб.
  2. В C\C++ появились новые типы и изменился размер некоторых старых типов.
  3. Использование fastcall в качестве calling convention (смотри MSDN).
Для тех, кто решит капнуть этот вопрос максимально глубоко следует обратиться к мануалам от Intel.

Что такое защищенный и реальный режимы работы?

Вопрос про режимы работы процессора напрямую связан с вопросом, что такое адресс в памяти и на мой взгляд является одним из самых важных вопросов, с которыми сталкивается программист в C\C++. Ошибки работы с памяти или интерпретации тех или иных адессов являются одними из самых частых на моей практике. К моему большому сожалению, многие современные программисты не понимают как работает память в современном компьютере.
В реальном режиме при вычислении линейного адреса, по которому процессор собирается читать содержимое памяти или писать в неё, сегментная часть адреса умножается на 16 и суммируется со смещением. Таким образом, адреса 0400h:0001h и 0000h:4001h ссылаются на один и тот же физический адрес, так как 400h×16+1 = 0×16+4001h.
Такой способ вычисления физического адреса позволяет адресовать 1 Мб + 64 Кб − 16 байт памяти (диапазон адресов 0000h…10FFEFh). 

Защищённый режим — режим работы x86-совместимых процессоров.
Суть защищённого режима в следующем: программист и разрабатываемые им программы используют логическое адресное пространство. Логический адрес преобразуется в физический адрес автоматически с помощью схемы управления памятью (MMU). При этом содержимое сегментного регистра не связано напрямую с физическим адресом, а является номером сегмента в соответствующей таблице. Благодаря защищённому режиму, в памяти может храниться только та часть программы, которая необходима в данный момент, а остальная часть может храниться во внешней памяти (например, на жёстком диске).

Физический адрес формируется следующим образом. В сегментных регистрах хранится селектор, содержащий индекс дескриптора в таблице дескрипторов (13 бит), 1 бит, определяющий к какой таблице дескрипторов будет производиться обращение и 2 бита запрашиваемого уровня привилегий. Далее происходит обращение к соответствующей таблице дескрипторов и соответствующему дескриптору, который содержит начальный 24-битный адрес сегмента, размер сегмента и права доступа, после чего вычисляется необходимый физический адрес путём сложения адреса сегмента со смещением из 16-разрядного регистра.
Вопрос про режимы работы процессора тесно связан со страничной организацией памяти и будет кратко рассмотрен в других постах. За дополнительной информацией можно обращаться в wiki или к различной литературе.

Сегменты, IDT, GDT, LDT, TSS(TR)?

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

Таблица векторов прерываний (IDT) используется в архитектуре x86 и служит для определения корректного ответа на прерывания и исключения.
Начиная с процессора 80286, адрес в физической памяти и размер таблицы прерываний определяется 48-битным регистром IDTR.
В IDT используются следующие типы прерываний: аппаратные прерывания, программные прерывания и прерывания, зарезервированные процессором, называемые исключениями (первые 32) на случай возникновения некоторых событий.
В реальном режиме элементом IDT является 32-битный FAR-адрес обработчика прерывания.
В защищённом режиме элементом IDT является шлюз прерывания длиной 8 байт, содержащий сегментный (логический) адрес обработчика прерывания, права доступа и др.

GDT (глобальная таблица дескрипторов) — служебная структура данных в архитектуре x86, определяющая глобальные сегменты. Её расположение в физической памяти и размер определяются системным регистром GDTR.
Дескрипторы LDT и сегментов задач (TSS) могут находиться только здесь.
Особенностью GDT является то, что у неё запрещён доступ к нулевому дескриптору. Обращение к нему вызывает исключение #GP, что предотвращает обращение к памяти с использованием незагруженного сегментного регистра.

LDT (локальная таблица дескрипторов). В отличие от GDT, LDT может быть много (соответственно количеству потоков, но не обязательно). Каждая задача может иметь свою. На расположение таблицы текущей задачи указывает регистр LDTR.
Размер и расположение LDT в линейной памяти определяются дескриптором LDT из GDT (но это не означает, что размер LDT может быть больше 65536 байт).

TSS (сегмент состояния задачи) — специальная структура в архитектуре x86, содержащая информацию о процессе. Может использоваться ОС для диспетчеризации задач, но обычно применяется только для переключения на стек ядра при обработке прерываний и исключений. В TSS содержится информация о:
  • Состоянии регистров процессора;
  • Разрешениях на использование портов ввода-вывода;
  • Указатели на стек внутреннего уровня;
  • Ссылка на предыдущую запись TSS (для задач диспетчеризации)
На этом на сегодня всё. Остальные ответы читайте в следующем посте.

Комментариев нет:

Отправить комментарий