Я милого узнаю по походке

Jan 22, 2019 09:01

В процессе восстановления исходного текста программы, про которую я рассказывал в давнем году, нашлась вот такая функция (выдача скрипта-декомпилятора слегка причёсана и приведена к сишному виду):

int func(int arg1, int arg2, int arg3) {
if (arg2 >= 3) goto a;
arg3 = arg3 - 1;
a:
arg2 = arg2 + 011;
if (arg2 <= 013) goto b ( Read more... )

puzzle, retrocomputing

Leave a comment

Comments 10

beldmit January 22 2019, 17:48:47 UTC
А что нынче носят в качестве декомпилятора?

Reply

spamsink January 22 2019, 19:39:43 UTC
Простенький самодельный дизассемблер на С++, расставляющий метки и восстанавливающий литеральные константы, плюс самодельный вырвиглазный скрипт на Перле, находящий границы функций/процедур и восстанавливающий операторы присваивания, выражения в условных переходах, и вызовы функций/процедур.

Если, в конце концов, решиться дизассемблировать всю операционную систему, то можно, наверное, замахнуться на прикручивание Radare, но современные тулзы настолько не рассчитаны на словные архитектуры с длиной слова, не кратной степени двойки, что ну его нафиг.

Reply


morfizm January 22 2019, 18:24:13 UTC
Не глядя и не вчитываясь - день недели выдавала по дате.
Параметры - день, месяц, год.

Reply

spamsink January 22 2019, 19:40:09 UTC
Конечно. Но там есть интересные детали.

Reply


rezkiy January 22 2019, 18:40:28 UTC
константы в восьмеричной системе -- издевательство над читателем.

Reply

spamsink January 22 2019, 19:43:31 UTC
Числа печатаются в восьмеричном виде, потому что маленькие целые числа неотличимы от символов (в кодировке ГОСТ-10859 коды полезных символов начинаются с нуля), а в восьмеричном виде коды символов легче узнаются, потому что в глубине памяти еще хранятся.

Reply


freeborn January 23 2019, 04:48:19 UTC
Замена 31/12 на 13/5 забавная, а -28 в конце не нужно

Reply

spamsink January 23 2019, 05:54:07 UTC
Это не замена, потому что 31 и 12 просто не работают. Фамилия "милого узнаваемого по походке" человека, придумавшего формулу, известна.

28 в конце, конечно, не нужно. Вопрос на понимание текста :) : откуда оно там взялось?

Reply

slobin January 23 2019, 17:08:55 UTC

Так, про формулу Целлера все уже ответили. Про -28 в конце: оригинальная формула Целлера под "остатком от деления на 7" подразумевает, строго говоря, не остаток, а модуль, величину заведомо положительную. А сишный % и аппаратура большинства процессоров выдают "остаток со знаком делимого". Поэтому для практического использования формулы нужно сделать величину, от которой берём остаток, либо заведомо положительной (прибавив, ну, скажем, 42), либо заведомо отрицательной (вычтя, ну, скажем, 28, и находя потом название дня недели по отрицательному смещению).

Бойцы вспоминают минувшие дни: единственная реальная проблема 2000 года, с которой я столкнулся, заключалась именно в этом: в коде эта константа была недостаточной, и в 2000 году день недели становился отрицательным. Исходников не было, после дезассемблирования проблема была решена нахождением нужного байта и увеличением его на 42. Я ответил на вопрос?

P.S. Кстати, в Аде есть обе эти операции отдельно, называются mod и rem. Чтобы человек сознательно выбирал, какая из двух ему сейчас ( ... )

Reply

spamsink January 23 2019, 18:46:59 UTC
То, что формула атрибутирована, кто-то может и не знать. С минус 28 всё проще: это рудимент от учёта столетия в оригинальной формуле (в приведенную функцию год даётся двузначный). Бездумно подставили, а упростить не подумали. В 20-м веке проблема разницы между mod и rem не стояла - номер года был настолько большой, что покрывал все возможные вычитания. В паскалевском оригинале, конечно, было mod.

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

Reply


Leave a comment

Up