Фак программисту. Или как понять свой старый код

Фак программисту. Или как понять свой старый код

Не так давно я вернулся к разработке zifi. Этот код был позаброшен больше 9 месяцев назад, и тогда я… устал продолжать :) Но — не забываю, есть старые проблемы, есть вновь найденные неудобства. Надо фиксить, надо развивать. Оболочка полезная вышла. Но, ччёрт, столько времени прошло… Как понять свой старый код через год? И как писать так, что-бы его можно было пОнять позже? Я выложу свои идеи по этому поводу, но хотелось бы услышать Ваши стандарты разработки.

Итак, мои личные рекомендации:

1. Не пишите код в линию. ld a,h, b,l,d,i: or a: jr z,milf — это замечательно, и настолько лаконично… но двояко, для меня лично. Это крайне слабо читаемо. Да, я понимаю — «сгущение» (не подберу другого слова) смысла в строках. Но читаемость кода, на мой взгляд — падает основательно. Из-за приёмов, подобных «ld a,h, b,l,d,i». Возможно, этот метод только лично мне не привычен, ок. Но код в строчку — читать не могу.

2. Разделяйте процедуры переносами строк. когда вы видите сплошную ленту дизасемблера — это одно. тут уж увы, не поформатишь, пожинай логику байтами. но в СВОЁМ коде — отделяйте блоки и процедуры друг от друга. визуальное восприятие блоками — резко повышает читаемость и восприятие логики каждой части программы. мало пары переносов — да пожалуйста, используй свои разделители в комментариях. важнее всего здесь — визуальное разделение блоков кода. Тебе его потом отлаживать.

3. Применяйте понятные метки. Время 8-ми байтовых меток давно ушло. Экономить не обязательно, не ZEUS. Для важных процедур стоит использовать метки, максимально описывающие — что делает процедура. Важно выделять важные места в программе, стараясь максимально понятно их называя:

Но! для незначащих переходов — стоит использовать короткие метки перехода sjasm — 1b, 1f:

Естественно, злоупотреблять ними не стоит; но я нахожу им отличное применение — вместо ненужных «названиефункции1» или «названиефункции3».

3.1. equ для меток Об этом нельзя сказать ничего плохого, но есть метод проще. Вместо чего-то типа:

заюзайте вариант попроще:

3.2. Ох, я намешал этих 2b / 1f, теряюсь! Сделай себе понятнее. Определи понятные метки вместо временных для тех, которые ВАЖНЫ. ибо временные метки важными не являются по определению. и хер ты на нужную сможешь сослаться.

4. Протестил — оформь процедурой. Всё обычно начинается с наброска, с теста — заработает ли, выйдет ли что-нибудь из этой затеи? но если уж всё получается — выдели этот блок, с умным и понятным именем в отдельную процедуру. что это даст?

упрощение отладки:

по сути — три щелчка по f8, и ты из прошёл. и если есть проблема — тут же ясно в какой именно процедуре зараза :) и да, давай процедуру с процедурами, окей?

5. Да всё понятно это, банальные вещи тулишь. Что делать с упрощением доступа к данным из асма, типа где IX+56 и т.д.? Замечательная проблема, приводящая к постоянной автозамене. Господа, юзайте структуры. вкратце: ld а,(ix+sprite.size_x) — здесь мы получаем доступ к необходимой ячейке по её имени с приставкой, к чему именно она принадлежит. описание её выглядит вот так (справедливо для sjasmplus):

для себя отмечаем, что эта структура — 6 байт в длину :) это даёт понятный код, и огромную простоту при переделке.

6. Хочу много одинаковых повторяющихся кодов и данных вперемешку, потому что у меня тьюринг! МАШЫНА! отлично! есть хорошее средство обьединить код и данные в группу — макросы. вместо определения макроса в код будет подставлено его содержимое. при этом — для макроса можно задавать входные параметры, что очень удобно. параметры и содержимое макроса будет лежать в памяти точно так-же, как и привычный код. Представь себе — что это подпрограмма, в которой можно заменить параметры описанные в заголовке.

приведу макрос, юзаемый мною в демах. он — без кода, и предназначен для указания, какая именно процедура будет вызываться в основном цикле. значимо здесь — номер команды (2), и адрес передаваемой процедуры:

  • VBI
  • 25 февраля 2017, 23:11
  • 10
  • 0
  • 2
102 комментария

Про 1. — резко нет. Чем дальше пишу, тем больше кода мне хочется иметь на экране. Так вот. Проблема не коде в строчку. Проблема в неудобных мнемониках и каше из разных частей кода в строке. Т.е., твои примеры «неправильные». К коду в строку отношения не имеющие.

Задумайся сам, зачем тратить на это 7 строк:

  • introspec
  • 25 февраля 2017, 23:25

Вообще, это мой интерес. Вопрос — как писать, сверху-вниз или слева-направо напрямую относится к психологии восприятия человеком, к работе ума. Тут не все так просто, не только вопрос удобства.

Логическая аргументация такова: Ход вычислений — сверху вниз. И когда мы располагаем их слева-направо, это осложняет нам восприятие хода вычислений, так как приходится постоянно «переключаться» от сверху-вниз к слева-направо. Это может быть аргументированно там где требуется и общепринято, например при вычислении выражений, но если особой ДОСТАТОЧНОЙ на то необходимости не имеется, лучше этого избегать.

Это «удобно» до той поры, когда ты «в теме», пока тебе заранее известно что происходит в данном фрагменте текста программы. Но как только ты утеряешь это представление, и тебе надлежит РАЗБИРАТЬСЯ (вот в чем разница), подобная запись немного, но осложняет восприятие. Является маленьким препятствием, местом преткновения. Вплоть до того что я иногда на автомате enter'ом возвращаю сложные строки обратно к представлению в столбец.

Ну и последняя аргументация. Если бежать и создавать к каждой строке комментарии отдельным столбцом, то подобные строки слишком широки и не дают нормально написать комментарии. К тому же, если будет столбец сплошных строк-комментариев, он «маскирует» такую длинную строку.

Так что… любой «выверт» имеет свою цену… :)

  • Raider
  • 26 февраля 2017, 18:45

Есть много теорий по этому поводу. Например, есть такая теория, что любой конечный кусок кода должен более-менее помещаться в экран, без скроллингов и т.п. Опять же, любая техника быстрого чтения как раз о том, чтобы не бегать глазами по строкам, а видеть целиком.

Я думаю, что большинство таких рассуждений — чисто размышлизмы. Но на практике, запись в столбик придумывали на экранах 30-40 символов в ширину. Не знаю насчёт тебя, а я сижу сейчас напротив экрана, который даёт мне в терминале 210 символов в ширину. Ты всерьёз думаешь, что сможешь убедить меня потратить 3/4 этого пространства на пустое место?

  • introspec
  • 26 февраля 2017, 19:05

Не вполне размышлизмы, с моей стороны это напротив, хардкорная практика, практика, практика. Сейчас конкретно я сижу перед браузером :) А вообще, бывает, работаю с кодом открывая три и даже четыре окна параллельно рядом друг с другом. Почему окна открываются слева-направо, четырьмя столбцами окон? Почему там код в столбец? Почему они не открываются друг-под-другом? (ну ок, два окна еще можно). И почему я матюгаюсь, скроллируя окошко влево-вправо, когда какой-то деятель нафигачил длинных строк? :)

Всерьез убеждаю тебя освоить редактирование с параллельным открытием нескольких окошек рядом… Дико удобно, да и если кто-нибудь видит, немедленно оценит твою крутизну :))))

  • Raider
  • 26 февраля 2017, 19:21
  • introspec
  • 26 февраля 2017, 19:32
  • PheeL
  • 26 февраля 2017, 21:14
  • Raider
  • 26 февраля 2017, 19:07
  • introspec
  • 26 февраля 2017, 19:31
  • Raider
  • 26 февраля 2017, 20:09

Ну просто сидя в каком-нибудь Intellisense редакторе, ты всерьёз будешь мне говорить что может возникнуть проблема от того что у кого-то 5 команд в строке? Ну да, чуть другой интерфейс понадобится, но несерьёзно это как аргумент выдавать.

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

  • introspec
  • 26 февраля 2017, 20:43
  • PheeL
  • 26 февраля 2017, 21:22
  • Raider
  • 28 февраля 2017, 14:11
  • introspec
  • 28 февраля 2017, 14:25
  • shinilb0g
  • 26 февраля 2017, 21:53

Про номер 3 язык уже сбил. Самый важный пункт.

Номер 3.1 — вкусовщина. Раньше я всегда писал (ololo+1), сейчас мне кажется, что это путает. Чаще ввожу специально явную ссылку. Но вообще, обычно у меня в одном исходнике обычно можно найти и так и эдак. Когда-нибудь преодолею…

Номер 4 — вкусовщина.

Номер 6 требует в качестве подпункта ссылку на макро-библиотеку Flying, которая не содержит ни одного компилируемого байта: zxpress.ru/article.php?id=3614

Реальный дзен и, если чуть серьёзнее, там и правда есть несколько хороших идей.

Хотя у меня всё не так! :)

  • introspec
  • 25 февраля 2017, 23:32

вкусовщина. приемлемо только по началу — одноразовое исполнение, но что делать потом? с кучей ссылок на ссылки и данными оттуда, которые ссылаются на данные.

либо же — быстрый но рабочий набросок за один вечер, который абсолютно был не описан но сегодня для тебя имеет значение как особенная реализация стандартной процедуры

  • VBI
  • 26 февраля 2017, 00:16
  • VBI
  • 26 февраля 2017, 00:17

Это ты про 3.1 «приемлемо только по началу — одноразовое исполнение, но что делать потом? с кучей ссылок на ссылки и данными оттуда, которые ссылаются на данные»? Ну да, ссылок больше. Но есть одно достоинство — ты не путаешь метки с данными. Пример из моего кода:

Видишь? Мне не нравится писать ld (trb_play+1),hl, потому что я начал рефактор, добавил команду и получил чудесные глюки. Да, это больше меток и труда. Но это реально лучше код.

  • introspec
  • 26 февраля 2017, 00:43

А вот с точки зрения рефакторинга — это хорошая, блестящая аргументация, которая бьет все остальное.

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

Соответственно, первая метка это имя функции для call/jump, вторая чисто для данных. Да, ее нельзя использовать «где-то там» без контроля, и это плохо, error-prone. Плохо уже помню, но кажется конструкций вида label equ $+1 в некоторый момент просто не было… Сейчас лучше использовать label equ $+1, еще и потому на других машинах встретится именно это.

  • Raider
  • 26 февраля 2017, 19:44

хех, а я вообще под fasm вот такую дичь умудрялся делать:

потом уже понял что это ну совсем не дело :)

  • wbcbz7
  • 28 февраля 2017, 20:26
  • shinilb0g
  • 28 февраля 2017, 20:51

У меня в старом коде из 1990х такого добра навалом. Во-первых, из-за того, что я не всегда умел работать с $. Во-вторых потому, что я написал много старого кода в Zeus, и любые недокументированные команды приходилось вводить точно так же, байтами. В-третьих, я тогда сидел в своём собственном отладчике, без дизассемблера, и помнил кучу команд наизусть, так что писать хексами мне было легко :)

Только отладчик у меня был в десятичной системе и команды я помнил в десятичной системе…

  • introspec
  • 28 февраля 2017, 22:16
  • sq
  • 1 марта 2017, 02:35
  • shinilb0g
  • 1 марта 2017, 06:02

VBI мне импонирует тем что у него упрощенный и правильный взгляд на мир. Все должно быть устроено просто. Нет, ну в самом деле, конструкция

вызывает кратковременное преткновение ума, необходимо пусть хоть и кратковременно, но все же понять что означает эта метка, вычислить ее значение в уме. Вместо equ $+1 для других команд там должно быть equ $+2 и даже equ $+3, а это уже error-prone.

Это основное. Такжке для логической аргументации можно упомянуть нарушение принципа verbosity в командах которые используют эту метку. ld (label+1),reg мне явно показывает что это само-модифицирующийся код, тогда как ld (label),reg такого не показывает, скрывает это от меня.

  • Raider
  • 26 февраля 2017, 19:03

Всё должно быть устроено ровно настолько сложно, насколько нужно! :)

Это не всегда означает просто, увы.

  • introspec
  • 26 февраля 2017, 19:52

Я скорее о том что существуют два вектора — люди в сторону усложнения, и люди в сторону упрощения. (Эйнштейн) «Все должно быть изложено так просто, как только возможно, но не проще.»

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

  • Raider
  • 26 февраля 2017, 20:17

Так пишут только мудаки!

ага и zeus отменили, да? Помести см себя на место другого, который будет использовать твой код на другом ассемблере.

а теперь сравни время набора такого кода и форматированного сырка. Учись читать, короче.

фак сам себе написал короче.

  • shinilb0g
  • 25 февраля 2017, 23:38
  • VBI
  • 25 февраля 2017, 23:49
  • introspec
  • 25 февраля 2017, 23:51
  • shinilb0g
  • 26 февраля 2017, 05:12
  • introspec
  • 26 февраля 2017, 12:46
  • shinilb0g
  • 26 февраля 2017, 12:49
  • kowalski
  • 26 февраля 2017, 00:18
  • VBI
  • 26 февраля 2017, 00:25

Код, само собой, от балды и смысла не несёт, оптимизировать не надо ) Штука в том, что метки с точкой «видны» только внутри блока, до следующей «обыкновенной» метки. Внутри второй процедуры я спокойно могу использовать имя .loop повторно, и ничего мне за это не будет ) Однако к такой метке можно при желании доступиться и извне, указав полный путь типа jp do_some_stuff.leave. Т. е. такая себе более удобная / приятная для понимания альтернатива вот этим вот всем 1b / 2f.

  • kowalski
  • 26 февраля 2017, 00:40
  • introspec
  • 26 февраля 2017, 00:47
  • kowalski
  • 26 февраля 2017, 01:04
  • introspec
  • 26 февраля 2017, 01:12
  • shinilb0g
  • 26 февраля 2017, 05:16

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

это нормально? Это я так понимаю всё ради компилятора не способного дать возможность построить таблицу чисел не подряд байтик за байтиком, а +256. И самое главное проводятся тесты, да ещё и плакать начинаем, что лишние 512 байт памяти в дырки ноликов превратились. А тестировать надо только оптимизированный код, вот такой:

Вот это читаемо LD H,HIGH(MULTAB), а так тестируют только мудаки LD H,MULTAB/512, тратящие место и главное такты на ограниченность компилятора. Слово мудаки я использовал только по отношению к тому кто его написал.

  • Robus
  • 26 февраля 2017, 01:19

Суров! Там кстати INC HL тоже не был нужен; INC L вполне прокатил бы.

Но меня заинтересовало другое. Умножение. У тебя что, тоже есть такая дрянь раскрянченая? Или ты вообще?

И, в любом случае, было бы здорово, если бы ты поделился, даже не самими процедурами своими, но примерно порядком — сколько, как ты считаешь, должно занимать знаковое умножение 8*8->8 и 8*8->16?

  • introspec
  • 26 февраля 2017, 01:38
  • shinilb0g
  • 26 февраля 2017, 05:14
  • VBI
  • 26 февраля 2017, 00:06
  • nodeus
  • 26 февраля 2017, 00:34
  • VBI
  • 26 февраля 2017, 11:37

Вспомнил ещё один мега-важный пункт.

Люди. Складывайте библиотеки в модули. Это реально упрощает жизнь.

  • introspec
  • 26 февраля 2017, 00:45
  • kowalski
  • 26 февраля 2017, 01:10
  • VBI
  • 26 февраля 2017, 11:59
  • sq
  • 26 февраля 2017, 03:49
  • shinilb0g
  • 26 февраля 2017, 05:21
  • Shiru
  • 26 февраля 2017, 10:48

это популярно скорее всего на комодоре. Видел я подобный код распаковки LZ4. пришлось просить помощи разработчика, код просто собирался неправильно.

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

  • shinilb0g
  • 26 февраля 2017, 11:18
  • VBI
  • 26 февраля 2017, 12:04

ты моего кода не видел(:

  • shinilb0g
  • 26 февраля 2017, 12:09
  • Raider
  • 26 февраля 2017, 20:21
  • shinilb0g
  • 26 февраля 2017, 20:54

Дядечка очень в тему топика получился. Зажог и смотрит.

  • nyuk
  • 26 февраля 2017, 22:20
  • DenisGrachev
  • 27 февраля 2017, 05:37

нет, ну это край, конечно(:

вполне логическая связка, годная для быстроты ввода.

  • shinilb0g
  • 27 февраля 2017, 09:16

Дело не только в скорости, а ещё и в том, что у тебя строка делает ЧТО-ТО ОДНО. Это как одна команда в каком-то языке чуть посложнее. Считай, ты макрос ввёл.

Потому что мы все имеем опыта программирования на более высоком уровне, выделение строки для каждой команды слишком «разбавляет» код. Да, я тоже терпеть не могу вереницы присваиваний

Но пора перестать мешать в кучу код в строку (нормальная идея) от синтаксиса шторма — это не одно и то же.

Голова не обязательно должна кружиться от кода в строчку:

Разумеется, любую, даже самую хорошую идею можно довести до абсурда. Но что это доказывает? Правильно, ничего.

  • introspec
  • 27 февраля 2017, 12:31
  • VBI
  • 27 февраля 2017, 15:17
  • Robus
  • 28 февраля 2017, 01:14
  • nyuk
  • 28 февраля 2017, 02:38

Robus, ну просто убери $ и все твои примеры станут сразу нормальными.

Т.е. проблема опять в том, что ты утрируешь немного. И хочешь писать по-своему. Но пойми, Вова напал на нас первый и мы (многокомандвстрочники) просто защищались. Я же не говорю всем как писать, я говорю что имею право писать и мне так удобно. И есть свои достоинства, далеко всё не чёрно-белое. А разные люди приходят и говорят, что ld b,c,d,e — плохая команда, и что $ в строке непонятно к чему привязать. А то, что у меня в коде нет ни первого и не второго видимо спросить забыли.

  • introspec
  • 28 февраля 2017, 03:43

Я не хочу что бы это называлось ЧИТАЕМЫЙ КОД! Это не читаемо, это не по правилам и не может нигде и не при каких обстоятельствах назваться читаемым. Называй это как хочешь, «фича», «супер удача», «невероятный прорыв мысли», но только никак не читаемый код. Читаемый это когда понятно что конкретно делает кусок кода. Я не говорю о том, что бы он был прост, а том что бы он был читаемым. А главное во всём этом совсем другое, это возможность инструмента, которым ты пользуешься. Возможность располагать больше кода на экране достигается выбором монитора с расширением и редактором способным работать с фонтом 6х7 пикселей, а не компилятором который даст тебе писать текст змейкой. Вот смотри я использую текстовый редактор только тот, который мне позволит работать с блоками текста, для построения таблиц. Я вообще не рассматриваю ни один редактор который не даёт мне такую возможность. Мне очень важно умеет ли он раскрашивать текст, но давать мне возможность отметить блок и порисовать в тексте на скорую руку картинки это важнее. Так что мне написать компилятор, что бы мог воспринимать магическую запись текстового редактора ради таблиц? Или тот же ALIGN, да всё равно что пишется текст спиралькой, это не экономит ни место в памяти ни такты процессора, без ALIGN для меня вообще нет компилятора. Он у меня вообще везде, и после ALIGN стоят не только 256, а 16, если таблица на 16 байт. А если надо что бы ALIGN не тёр до границы ноликами есть ORGALI, я на этом всём пишу прошивки для флешек, где надо генерировать HEX файлы, в которых нужно делать дыры из ничего вообще, просто пространство. Эти инструменты важнее на порядок записи в строчку. И речь идёт не о том, что ты пишешь не верно, а том, что этот код не читаем. ALIGN 256 это чёткое описание твоего желания, а ORG ((($-1)/256)+1)*256 это частный случай с учётом повезёт тебе с округлением или нет, и что бы ты не говорил это не читаемо. Можешь написать туда MOD, это так же не читаем. Это всё равно что описывать «if» через «for», поверь, я могу тебе сделать анализатор-генератор СИшного кода и поменяю местами все if и for, и это откомпилирует, но опять таки это не читаемо. Я понимаю, если бы вы обсуждали макросы, что-то типа вот такого:

Я верю, что каждый может в строчку написать сто-тыщ операций, но это не читаемо. Читаемы слова, объясняющие что ты там на прерываниях делаешь. И потом когда будет происходить «дебаг», править надо будет только макрос, в котором через двоеточие, по спиральке, змейкой и крестиком пиши как угодно. Опять-таки я не говорю про простой код, пусть он будет сложный, пусть будет ветвистый и выжатый до последнего такта, но максимально читаемый. А каждый пример который был тут приведён не несёт оптимизации, и не несёт информативность, он несёт только фичу. И я ещё раз говорю, слово «мудак» я применяю только к тому, кто его применил ко мне. И да, я очень сильно разозлился, кода прочитал что я «мудак» только лишь потому, что кто-то вышивает крестиком, да ещё постыдно это называет читаемый код.

  • Robus
  • 28 февраля 2017, 04:44

Ну вообще-то мудаком в упомянутом тобой случае оказался и я тоже, так что непонятно даже.

А про код… ну я на самом деле сейчас в некотором недоумении, потому что тут просто удивительно сколько людей поругались сейчас из-за удивительно ничтожного повода. Ну вот я внимательно прочёл. Вертикальные блоки. Макросы. Ну если очень коротко, у нас разное понимание что такое читаемость. У Raidera одна, у тебя — другая, у меня как видишь третья оказалась. Не знаю что делать по этому поводу. Для начала, наверное, нужно перестать по этому поводу ссориться.

📎📎📎📎📎📎📎📎📎📎