I Введение (на примерах ассемблерных программ)
История вычислительной техники. Архитектура фон Неймана. Основные компоненты компьютера. Машинная команда, типы операндов, адресность ЭВМ, такт работы. Упрощенная схема выполнения инструкции.
Упрощенная схема компиляции Си-программы в окружении компилятор gcc, операционная система Linux, архитектура IA-32 и ее связь с архитектурами 8086 и Intel64. Архитектура IA-32: основные регистры, форматы команд. Представление машинной команды, ассемблерная инструкция. Декодирование и дизассемблирование.
Организация ассемблерной программы, секции кода и данных. Пример ассемблерной программы: пересылка данных, арифметические операции, регистр флагов.
Передача управления. Пример ассемблерной программы: условные и безусловные переходы. Разбор задач на восстановление конструкций языка Си: выражений и управляющих конструкций.
Проблемы организации вызова функций. Аппаратная поддержка стека. Пример ассемблерной программы: отображение вызова функции языка Си в язык ассемблера.
II Взаимосвязь языка Си, языка ассемблера и особенностей архитектуры IA-32
Различные группы команд в архитектуре IA-32. Реализация арифметических операций над 64-разрядными целыми в архитектуре IA-32. Команды «быстрой» арифметики. Побитовые логические инструкции. Инструкции сдвига и вращения. Операции над отдельными битами.
Отображение операторов разыменования указателя и взятия адреса из языка Си в язык ассемблера. Размещение различных типов переменных языка Си в памяти компьютера. Пример работы с указателями. Одномерные массивы и указатели. Адресная арифметика.
Многомерные и многоуровневые массивы. Расположение в памяти, способы работы с отдельными элементами.
Организация работы со структурами и объединениями языка Си на уровне языка ассемблера. Доступ к полям. Различные правила выравнивания данных: Windows/Linux, Intel64. Битовые поля структур.
Различные способы отображения оператора switch в язык ассемблера: последовательность if-else, таблица переходов, дерево выбора.
Условная передача данных: goto-форма представления ветвлений и циклов. Отображение операторов цикла языка Си в язык ассемблера. Организация цикла с помощью инструкции LOOP.
Особенности работы компилятора с массивами: примеры простых оптимизаций: примеры машинно-независимой и машинно-зависимой оптимизации.
Соглашение о вызове функций cdecl. Распределение памяти во фрейме функции. Организация рекурсии.
Возвращаемое значение в соглашении cdecl, возврат структур из функции в компиляторе gcc.
Выравнивание фреймов в стеке. Организация вызова функций стандартной библиотеки языка Си из ассемблерного кода.
Ассемблерные вставки в Си-программах. Ускорение вызова функций и возврата из них: реализация вызова функций без указателя фрейма, соглашение fastcall.
Функции с переменным числом параметров. Вызов функции по указателю. Обратный вызов. Соглашение вызова Intel64. Значимые отличия между Intel64 и IA-32.
Поддержка динамической памяти в Си-программе. Организация динамической памяти: неявные и явные списки, граничные теги. Неявное управление динамической памятью: сборка мусора.
Формат инструкций архитектуры IA32. Префиксы: модификаторы размера операнда и адреса, префиксы повтора. Реализация операций над строками.
Представление чисел с плавающей точкой. Стандарт IEEE 754. Операции над числами с плавающей точкой. Округление чисел.
Сопроцессор FPU x87. Аппаратный стек регистров. Числа с плавающей точкой в языке Си: типы, доступ к результатам сравнения чисел, передача в качестве параметров функции, возвращаемое значение.
III Архитектура ЭВМ
Организация аппаратного обеспечения компьютера. Логические вентили. Закон Мура. Закон Гроша. Различные классы вычислительных устройств: микроконтроллеры, мобильные устройства, настольные компьютеры и серверы, суперкомпьютеры.
Устройство оперативной памяти. Статическая и динамическая память. Расслоение памяти.
Организация ввода/вывода. Шины, их характеристики, примеры шин: фронтальная шина, PCI, USB, SATA … Атомарные операции, захват шины данных при обращении к памяти.
Пример периферийного устройства: НЖМД. Устройство, организация доступа к хранимой информации, емкость, временные характеристики доступа. Организация ввода/вывода через пространство портов и через память. Прямой доступ к памяти периферийных устройств. Твердотельные диски.
Тенденции в развитии запоминающих устройств. Локальность в программах. Иерархическая организация памяти, кэширование. Кэш-память процессора, способы ее организации: кэш прямого отображения, N-канальный ассоциативный кэш, полностью ассоциативный кэш. Метрики производительности кэш-памяти.
Способы оценки производительности компьютеров и программ. Аппаратные средства измерения времени. Синтетические тесты: оценка производительности памяти современного компьютера, варьирование локальности при умножении матриц.
Конвейерная обработка команд. Приостановка и опустошение конвейера. Суперскалярная архитектура. CISC и RISC архитектуры на примере Intel64 и ARM.
История развития архитектуры x86. Обратная совместимость процессоров (на примере линии A20).
Многозадачная работа компьютера: требования к аппаратуре, работа с памятью в защищенном режиме. Прерывания: программные, аппаратные, исключения. Системный вызов.
Сегментная и страничная организация памяти. Логические, линейные и физические адреса памяти.
Режимы работы современного процессора архитектуры Intel64/AMD64: реальный, защищенный, «длинный», режим совместимости, режим системного управления. Процесс загрузки компьютера.
Многопроцессорные и многоядерные компьютеры. Проблема синхронизации работы нескольких вычислительных ядер. Пример реализации циклической блокировки.
IV Система программирования языка Си и ее связь с архитектурой ЭВМ
Система программирования языка Си. Программные инструменты, используемые при разработке Си-программ. Схема работы ассемблера. Статическая компоновка программы. Схема работы компоновщика: разрешение символов и перемещение кода. Типы объектных файлов (модулей). Формат ELF.
Обработка компоновщиком нескольких символов с одинаковыми именами: сильные и слабые символы. Организация многомодульной программы, роль заголовочных файлов. Статические библиотеки. Компоновка со статическими библиотеками. Загрузка исполняемого файла в память.
Программные утилиты для работы с объектным кодом. Динамическая компоновка. Позиционно независимый код. Динамические и разделяемые библиотеки, особенности организации и загрузки.