Программирование и отладка на C и ASM

Материал из MediaWiki
Перейти к навигации Перейти к поиску

Книга будет посвящена программированию на языке Си и ассемблера, притом они будут рассказываться параллельно, т. е. на примере кода на ассемблере будет объясняться Си, и на примере кода на Си будет объясняться ассемблер. Кроме того, будет затронута тема отладки через GDB, использование strace, ltrace, valgrind. Будет рассказано про системные вызовы и прочее…

Неструктурированный поток информации, которую надо разложить на разделы, главы: Сначала будет традиционный «hello world» и его детальный разбор. Будет написано несколько хеллоувордов, один будет состоять из одного puts(), другой — из вызовов двух puts(), третий — из write(STDOUT_FILENO) и четвертый — из двух write(). Будет сказано про то, что из себя представляет строка (нуль‐терминированная Си строка — предполагается использование символов только из набора ASCII). Будет про то, как скомпилировать чтобы получить объектные файлы, и потом слинковать (через ld). Но и про случай с линковкой через gcc сразу (хотя GCC будет там в любом случае под капотом вызывать ld, об этом надо непременно сообщить). Про то, как получить ассемблерный листинг от компилятора (опция -S) и это будет применено к всем видам хеллоувордов, с последующим объяснением, что конкретно значат эти ассемблерные листинги. Про дизассемблирование через objdump тоже будет непременно сказано. Будет приведен пример «хеллоуворда с ошибкой», т. е. например если сделать не нуль‐терминированную строку (просто массив, который нулем не заканчивается), попробовать ее вывести через тот самый puts и пробовать запустить это. Это же применительно к write(STDOUT_FILENO) с размером, превышающим фактический размер строки. Запуск вариантов с ошибками и без ошибок под под valgrind, strace, ltrace. Про отличия puts от write(STDOUT_FILENO), рассказ про системные вызовы, файловые дескрипторы. Рассказ о том, как через open или fopen создать файл и вывести в него текст через write и fputs.

Дальше: пользовательский ввод через gets, read из stdout. Например, программа пишет «введите свое имя» — ожидает ввода имени — отвечает привет, %имя%.. Чтение из файлов через read fgets (надо открыть через open fopen, прежде чем читать, и чтобы было разрешение на чтение — это понятно). Примеры ошибок, позапускать через valgrind. (пока что на таких примерах показать полезность отладчика — задача нелегкая. Надо будет подумать насчет того, чтобы сделать некий специально ошибочный код, и попросить в нем выловить баги через отладку). Позапускать через strace ltrace.

Дальше: арифметические операции, обычные goto и метки, конструкция if (условие) goto метка. Простейший цикл из if (условие) goto метка, который делает нечто n‐ное количество раз, например выводит «hello world». Разбор ассемблерного выхлопа. Разбор конструкции if (условие) {действие;} и ассемблерного выхлопа. Аналогично для конструкции if (условие) {действие;} else {действие;}. Рассказ о том, что такое {} (скоуп, область видмиости, блок кода). Понятие «стека» в ассемблере для выделения памяти под локальные переменные. Небольшой такой рассказ про глобальные переменные, чем отличается объявление глобальной и локальной переменной с т. з. ассемблера. Рассказ про циклы и их эквивалентность (заменяемость) конструкцией if (условие) goto метка. Теперь уже можно «побродить» по коду через отладчик, посмотреть как «исполняемое» место через эти if—goto и циклы перепрыгивает.

Можно пообъяснять ассемблер поподробнее, и попросить что‐то писать непосредственно на ассемблере, а не только читать код, выдаваемый компилятором

Дальше — больше. Текст плана работ находится в процессе доработки.

Начало положено: Программирование и отладка на C и ASM — Первые программы. Знакомство с C и ассемблером. Компиляция, линковка, код возврата. Вывод текста.