Итак, я решил написать(или как вариант, собрать из кусочков) книгу-самоучилель по программированию, в которой бы не было глупых и нелепых ограничений на распространение. Однако копилефт я все же считаю приемлемым в данном случае. Общественным достоянием это не будет т.к. вполне могут найтись желающие использовать результат в своих проприетарных книгах, а проприетарные книги — плохо. Лицензия самого текста книги-учебника будет или Creative Commons Attribution-ShareAlike (что позволит без каких-либо проблем переиспользовать текст из википедии) или что-то вроде GNU Free Documentation License (без неизменяемых разделов естественно).
Лицензии всяких примитивных программок, написанных мной лично, будут вообще выложены под общественным достоянием, WTFPL или аналогичной лицензией т.к. являются тривиальными. Примерно вот так. Если я буду использовать чужие исходные тексты, они будут как включения, лицензируемые отдельно от всего остального. Проблем тут быть не должно.
Теперь к теме того, на кого книга ориентирована, какие начальные знания предполагаются, чему книга будет учить, какой первый ЯП взять и каков будет авторский самысел:
С этим моментом я пока что не определился окончательно, и тут есть что обсудить. В частности, я не вижу особого смысла объяснять какие-то базовые понятия комбинаторики, об этом можно доступным языком прочитать из школьных учебников. Системы счисления(СС), перевод из одной СС в другую - вот это еще можно. One's и two's complement представления знаковых чисел — про это тоже можно написать. Если же человек не понимает комбинаторику, он ее быстро поймет на примере кода, который будет достаточно наглядно это показывать, и который всенепременно будет.
Пока что в качестве первого языка я склоняюсь к Си, и тому есть причины. Все прочие распространенные языки (кроме ассемблера, хотя его трудно назвать распространенным) не настолько близки к аппаратному уровню. Про нужность понимания на низком уровне написано тут http://russian.joelonsoftware.com/Articles/BacktoBasics.html https://habrahabr.ru/company/piter/blog/271347/ , не вижу смысла повторяться. Приведу лишь цитату:
«Просто плохой воркшоп попался», — скажете вы. Но на этом примере я хочу подчеркнуть более масштабную проблему: не изучив для начала C, программист оказывается лишен необходимых орудий, позволяющих понять, что именно происходит в используемой системе. Если вы — умный и пытливый питонщик, то вскоре докопаетесь до плотных пород языка C. Под этими горизонтами, скажут вам, «бойся драконов, костей и отладчиков». Соответственно, если вы не будете достаточно отважны и не проигнорируете предупреждений «да не берись ты за этот C», вы никогда не исследуете глубин, на которые можно забраться просто из любопытства.
Притом еще один важный момент: Си будет изучаться параллельно с ассемблером. Если речь идет об изучении ассемблера, необходимо четко зафиксировать то, на какой архитектуре это все происходит и в какой ОС. Так вот, ОС будет GNU/Linux а архитектура x86-64. Будут постоянно проводиться параллели между тем, что из себя представляет код на Си в текстовом виде, и тем, в какой текст на ассемблере его превращает компилятор. В связи с этим, первым делом будет рассказано о goto
и конструкции if(условие) goto метка;
. Про конструкции вида
if(условие)
{
что-то_делаем;
}
else
{
что-то_другое_делаем;
}
Будет рассказано немного позже, притом это будет рассказано и словами, и через написание эквивалентного кода через
if(условие) goto метка;
. Циклы,
for(){} while{}, do{}while()
, конструкция
switch-case
и
break continue
внутри них будут так же объясняться через все тот же
if(условие) goto метка;
притом будет делаться явный акцент на том, что намного лучше использовать нормальные циклы, чем лепить всюду этот условный goto. Кроме того, будет так же рассказано про
Labels as Values. Почему так важна эта странная штука,
if(условие) goto метка;
? Потому что она имеет наипрямейшее отношение к тому, как работают ЭВМ, а всякие циклы СКРЫВАЮТ это. Рекурсия в Си будет объясняться только после того, как будет объяснено, что такое стекфрейм и соглашения вызова, будет сказано про оптимизацию хвостовой рекурсии, и о проблеме забивания стека, если такая оптимизация не происходит, притом это будет наглядно показано в ассемблере. Учиться отлаживать код надо будет тоже «с пеленок», притом отлаживать и ассемблер, и всякие там Си. Будет и про асм-вставки в Си, clobber list. В качестве ассемблера будет рассматриваться GAS, а никакой не NASM т.к. GCC умеет выплевывать ассемблер именно в GAS синтаксисе. Насчет выбора Intel или AT&T синтаксиса - тут я склонюсь пожалуй к тому, что надо ЗНАТЬ И УМЕТЬ ПОНИМАТЬ ОБА. Кроме того, GAS давно уже умеет в оба синтаксиса, так что проблем с этим не будет. Единственная проблема с GAS в том, что это однопроходной ассемблер, так что можно освоить и какой-нибудь NASM, YASM.
Первые хеллоуворды будут написаны вообще в особом стиле, без использования printf()
и вообще без библиотеки Си; Будут использованы куски на ассемблере, которые делают системный вызов write и read, и с ними можно(нужно) будет линковаться, чтоб что-то вывести на экран. Будет рассказано и про printf
естественно, но только когда будет совершенно четко ясно, что такое вообще va_list
. Будет куча отсылок к драфту стандарта Си (недрафт почему-то платный). Будет так же рассказано про устройство ОС. В конце скорее всего будет дано задание сделать свою игрушечную ОС так что предполагается что человек к тому моменту должен уже отлично понимать всякие там связные списки, графы, очереди, спинлоки-аллокаторы свои уметь делать на асме при желании. Алгоритмы сортировки, обхода графов, хеш-таблицы, все это будет объяснено на языке Си, и плюсов вообще касаться я не буду.
Насчет графики: работу с протоколом иксов тоже можно будет рассказать, обработку нажатий клавиши. Правда там надо дофига писать про кучу всего, например что есть сокеты, есть AF_LOCAL... Тогда это можно еще и сетевому программированию учить на каких-нибудь беркли-сокетах.
Кроме того, после моей книги предполагается, что человек должен уметь заниматься такими ненужными (в GNU/Linux) на первый взгляд вещами, как крякинг, реверсинг, исправление ошибок в бинарниках, не обладая исходным текстом. Восстановление логики работы программы по дизасму. Ну и программирование в машинных кодах (без ассемблера, одним HEX редактором).
Как-то уж слишком дофига, не находите? Может быть не надо так глубоко во все это нырять? Жду предложений и критики по поводу того, что нужно, а чего не нужно писать. Возможно что я слишком много хочу.
cast ASM be_nt_all mister_VA
UPD: Программирование и отладка на C/ASM - Первые программы. Знакомство с C и ассемблером. Компиляция, линковка, код возврата. Вывод текста.