Языки программирования

Учебник Ассемблер для начинающих

23 урока · 6 разделов · бесплатно, без регистрации

Этот курс показывает, что происходит «под капотом» любой программы: как процессор хранит числа в регистрах, читает команды из памяти и шаг за шагом их исполняет. Мы пишем на ассемблере x86-64 в синтаксисе NASM под Linux, разбираем дополнительный код, систему команд, переходы, стек и соглашения вызова System V, делаем системные вызовы напрямую и смотрим, во что компилятор превращает обычный код на C. Курс для тех, кто уже знаком с любым языком высокого уровня и хочет понять машину по-настоящему: не чтобы писать на ассемблере каждый день, а чтобы перестать бояться слов «регистр», «стек» и «дизассемблер».

Курс «Ассемблер: как процессор исполняет код» состоит из 6 разделов и 23 уроков: Что такое ассемблер и зачем он нужен, Регистры, флаги и память, Представление чисел, Система команд, Управление потоком и функции и Память, ввод-вывод и связь с C. Уроки идут по порядку — от основ к более сложным темам, в каждом есть объяснение с примерами, а в конце — вопросы для самопроверки. К урокам привязаны задачи с автоматической проверкой: прочитали тему — сразу закрепили её кодом.

Программа курса

  1. 1 Что такое ассемблер и зачем он нужен

    1. Машинный код, ассемблер и язык высокого уровня

      Чем машинный код отличается от ассемблера и от Python: три уровня одной программы и место ассемблера между ними.

    2. Архитектура x86-64 и цикл исполнения

      Как устроен процессор x86-64: регистры, АЛУ, шина памяти и цикл fetch-decode-execute на простом примере.

    3. Первая программа: структура файла NASM

      Секции .data, .bss и .text, метка _start и точка входа: из чего состоит минимальная программа на NASM под Linux.

  2. 2 Регистры, флаги и память

    1. Регистры общего назначения и их части

      16 регистров x86-64, их 64/32/16/8-битные части (rax/eax/ax/al) и зачем такая матрёшка.

    2. Регистр флагов: ноль, знак, перенос

      Флаги ZF, SF, CF, OF в RFLAGS: как операции их выставляют и зачем они нужны для условий.

    3. Память и режимы адресации

      Как обращаться к памяти в ассемблере: квадратные скобки, базовый адрес, индекс, масштаб и смещение.

  3. 3 Представление чисел

    1. Двоичная и шестнадцатеричная системы

      Биты, байты, степени двойки и удобство hex: как одни и те же числа выглядят в разных системах счисления.

    2. Дополнительный код: отрицательные числа

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

    3. Знаковые и беззнаковые операции

      Почему процессор различает знаковые и беззнаковые числа: movzx/movsx, переполнение и выбор переходов.

  4. 4 Система команд

    1. Пересылка данных: mov, lea, обмен

      Команды mov, lea и xchg: как класть значения в регистры, вычислять адреса и обмениваться данными.

    2. Арифметика: add, sub, mul, div

      Целочисленная арифметика в ассемблере: сложение, вычитание, умножение и деление с участием rax/rdx.

    3. Логика: and, or, xor, not

      Битовые логические операции в ассемблере: маски, проверка и установка флагов, идиома xor для обнуления.

    4. Битовые сдвиги: shl, shr, sar

      Сдвиги влево и вправо в ассемблере: умножение и деление на степени двойки, логический и арифметический сдвиг.

  5. 5 Управление потоком и функции

    1. Метки и безусловный переход jmp

      Метки как адреса и команда jmp: как менять порядок исполнения и почему линейный код это иллюзия.

    2. Условные переходы и ветвления

      cmp плюс je/jne/jg/jl: как собрать if-else из сравнения и условного перехода в ассемблере.

    3. Циклы на ассемблере

      Как собрать цикл for и while из метки, счётчика, cmp и условного перехода; команда loop.

    4. Стек: push и pop

      Как устроен стек в памяти, как работают push и pop и почему стек растёт вниз по адресам.

    5. Вызов функций: call и ret

      Как call сохраняет адрес возврата на стеке, а ret его забирает: механика вызова функции в ассемблере.

    6. Кадр функции и соглашение System V

      Пролог/эпилог, кадр стека через rbp и передача аргументов в rdi/rsi/rdx по соглашению System V.

  6. 6 Память, ввод-вывод и связь с C

    1. Массивы и строки в памяти

      Как массивы и строки лежат в памяти, обход по индексу, нуль-терминированные строки в стиле C.

    2. Системные вызовы: syscall в Linux

      Как делать ввод-вывод через syscall в Linux: номер вызова в rax, аргументы в регистрах, вывод строки и exit.

    3. Как C компилируется в ассемблер

      Что компилятор делает с кодом на C: пролог/эпилог, godbolt, оптимизации и чтение сгенерированного ассемблера.

    4. SIMD-обзор и отладка в gdb

      Что такое SIMD и регистры xmm, как gdb помогает шагать по командам, смотреть регистры и дизассемблировать код.