Это популярное сообщение. Dennis_Chikin 3 658 Опубликовано 30 Января 2015 Это популярное сообщение. Поделиться Опубликовано 30 Января 2015 (изменено) Судя по регулярно происходящему в других темах - таки нужна.Вот здесь как раз можете спросить про "зачем создали эту тему ?" А также про ООП, про как заниматься моддингом и его устарелости неустарелости, кто как его себе представляет и т.д. В общем, для много слов "обо всем". Что в более специализированные темы не лезет, но поговорить давно хотелось и хочется. Но таки да, пп 2.0, 2.1 и даже 2.5 правил здесь вполне таки действуют. Изменено 30 Января 2015 пользователем Dennis_Chikin 5 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
abramcumner 1 146 Опубликовано 7 Апреля 2018 Поделиться Опубликовано 7 Апреля 2018 5 минут назад, НаноБот сказал: @abramcumner Оператор ORG в асме, это задать адрес кода, без него всё это невозможно. Я знаю, что такое ORG, и еще раз повторю ORG в асме, в с++ extern. И плюс, у компилятора куча ограничений, не не получится, С/С++ невозможно использовать в XRayExtensions проекте. Нет у компилятора никаких ограничений, с++ может генерировать точно такие же объектники, как и асм. Ну и я как бы делал хрей-экст на с++ Ссылка на комментарий
НаноБот 740 Опубликовано 7 Апреля 2018 Поделиться Опубликовано 7 Апреля 2018 1 час назад, abramcumner сказал: extern Это внешняя функция, ну а как задать собственно адрес задать? org 10227DAAh - shift А как такая строчка в С++ будет выглядить? ...в конце концов, важен лишь, машинный код. СТАЛКЕР только для ПК! Ссылка на комментарий
abramcumner 1 146 Опубликовано 7 Апреля 2018 Поделиться Опубликовано 7 Апреля 2018 20 минут назад, НаноБот сказал: А как такая строчка в С++ будет выглядить? Эта строчка так и останется в xrgame_stubs.asm. org 105602E8h - shift g_Actor dword ? В с++ напишешь: extern CActor* g_Actor; И можешь обращаться к g_Actor из c++. Ссылка на комментарий
НаноБот 740 Опубликовано 21 Мая 2018 Поделиться Опубликовано 21 Мая 2018 (изменено) В 01.04.2018 в 04:57, Malandrinus сказал: Это как? Может у тебя версия старая? Новая, старая, какая разница, МАСМ глючный, забагованный ассемблер. Но есть альтернатива, например UASM, МАСМ совместимый ассемблер с расширенными возможностями. Есть ещё asmC, так же форк JWasm, как и UASM. Правда в этих ассемблерах нет оператора для вычисления выражения, но это можно подправить. Исходники UASM и asmC выложены на ГитХабе. ЗЫ Интересно эти ассемблеры не являются на все 100% совместимыми с МАСМ, так как у них более высокие требования к ошибкам, но если эти ошибки устранить, то всё заработает. ЗЫЫ И ещё UASM быстрей компилирует, гораздо быстрей, проект XRayExt для ТЧ всего за 0.6 сек, что по сравнению с МАСМом быстрей в 28 раз! Изменено 21 Мая 2018 пользователем НаноБот ...в конце концов, важен лишь, машинный код. СТАЛКЕР только для ПК! Ссылка на комментарий
Malandrinus 615 Опубликовано 24 Мая 2018 Поделиться Опубликовано 24 Мая 2018 On 5/21/2018 at 7:43 PM, НаноБот said: МАСМ глючный, забагованный Не замечал за MASM особенных багов. Максимум, что мне от него было надо - компилировать код, генерируемый IDA. С этим MASM вполне справлялся. Единственная проблема была с версией 6 из состава Masm32. Но там был не баг, а просто старая версия, которая не поддерживала новые инструкции процессора. С трудом себе могу представить, что такое надо написать, чтобы ассемблер начал глючить. Если же речь идёт о глюках в препроцессоре, то это в ассемблере вообще от лукавого. On 5/21/2018 at 7:43 PM, НаноБот said: UASM быстрей компилирует, гораздо быстрей, проект XRayExt для ТЧ всего за 0.6 сек, Можно подумать, у тебя проект с компиляцией в пару часов. Не напомнишь, какая вообще мотивация продолжать использовать ассемблер? Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
НаноБот 740 Опубликовано 6 Июня 2018 Поделиться Опубликовано 6 Июня 2018 (изменено) В 25.05.2018 в 00:28, Malandrinus сказал: Не замечал за MASM особенных багов. Если кодить на чистом ассемблере, то проблем особо нет. Но я активно использую макрокоманды .if, .while, proc и тд. а вот они то, и не работают как надо. Например: .if (esi && g_alive(esi)) ... .endif Компилируется с ошибками, сначала идёт макрос g_alive. а затем проверка esi. В общем, мне не нужен С/С++, а нужен ассемблер высокого уровня с операторами высокого уровня, как в С/С++, с поддержкой ООП, типов, оператор выражения и так далее. Короче, UASM это частично решает, поэтому придётся его допиливать самому, потом может с разработчиками свяжусь чтобы мой код со своим слили. Новость! https://news.microsoft.com/2018/06/04/microsoft-to-acquire-github-for-7-5-billion/ Мелкософт купил GitHub! Вопрос? Чем нам это грозит? Изменено 6 Июня 2018 пользователем НаноБот ...в конце концов, важен лишь, машинный код. СТАЛКЕР только для ПК! Ссылка на комментарий
Malandrinus 615 Опубликовано 7 Июня 2018 Поделиться Опубликовано 7 Июня 2018 10 hours ago, НаноБот said: сначала идёт макрос g_alive. а затем проверка esi. Вот здесь я не понял. А как ты хотел, чтобы макрос препроцессора выполнялся на этапе выполнения программы? В целом то, что ты делаешь, - это путь в никуда. Ассемблер существует с единственной целью - чтобы компилировалось ровно то, что написано. Это важно, это изначальная суть ассемблера - последовательность инструкций процессора. Ты смотришь на код и точно знаешь, что получишь в итоге. У тебя же идёт уход в прямо противоположную сторону - нагромождение макросов препроцессора и даже кодогенерирующих директив (типа того же .IF). Какой в этом смысл? Такими вещами гораздо удобнее заниматься в языках высокого уровня, а ассемблер оставить для сугубо ограниченных целей: критические по производительности моменты и непосредственный доступ к железу в драйверах. Были бы у меня исходники изначально - не потратил бы ни секунды на всю эту возню с ассемблером. Более непроизводительного, неудобного и глючного способа писать код я в жизни не видал. Впрочем, у меня тогда не было другого выхода. Я отчётливо помню тот момент, когда решил влезть во всю эту историю с ассемблером. Я тогда для гравипушки придумал крайне извращённый способ отловить нажатие клавиши огня - по отлову быстрого расхода патронов. После этого я и понял, что это - предел и дальше чистыми скриптами ничего не развить. И тут как раз связался с Колмогор-ом насчёт этого его способа делать правки. Оттуда и завертелось. Но вот мотивации заниматься этим сейчас я не понимаю. Впрочем, каждому своё. 10 hours ago, НаноБот said: Чем нам это грозит? В ближайшей перспективе ничем. Вроде пока ничего не собираются менять. А даже если и закроют - полно других свободных хостингов. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
НаноБот 740 Опубликовано 7 Июня 2018 Поделиться Опубликовано 7 Июня 2018 Мне не нравится С++, особенно С++11 и более новые редакции, я просто не умею этой новой всей фигнёй пользоваться. Вот пример. Скрытый текст #include <iostream> #include <map> #include <stack> #include <functional> #include <utility> #include <stdlib.h> using namespace std; int main(int argc, char** argv) { stack<double> s; stack< pair<int, char> > ops; auto p = [&s, &ops] (function<double (double, double)>& f) { double r=s.top(); s.pop(); r=f(s.top(),r); s.pop(); s.push(r); ops.pop(); }; map< char, pair< int, function<double (double, double)> > > m ={ {'+', {1, [](double a, double b){return a+b;}}}, {'-', {1, [](double a, double b){return a-b;}}}, {'*', {2, [](double a, double b){return a*b;}}}, {'/', {2, [](double a, double b){return a/b;}}} }; const int order = 2; int level = 0; for (char* sp = argv[1];; ++sp) { while (*sp == '(') { level += order; ++sp; } s.push(strtod(sp, &sp)); while (*sp == ')') { level -= order; ++sp; } if (!*sp) { while(!ops.empty()) p(m[ops.top().second].second); break; } const int op = m[*sp].first + level; while (!ops.empty() && ops.top().first >= op) p(m[ops.top().second].second); ops.push(make_pair(op, *sp)); } cout << s.top() << endl; return 0; } Я просто не понимаю это нагромождения заумного кода, ЧЁ, код читабельный, код оптимальный, да ладно. За годы ковыряния IDA Pro XRay-я, я изучил как компилирует С++, и какой код эффективный, а эффективный именно простой код, так же такой заумный код трудно отлаживается, если есть ошибка, то найти её не просто. Короче, С++ в последних редакциях просто чудовище, VS2017 весит аж 36 ГигаБайт, это уже не гипербола, это реальное чудовище. Давно заметил что программисты на С++ используют сложные методы, там, где можно обойтись более простыми методами. Ну типа колёса в технике определяют как vector или даже как map, хотя по факту это совсем не к чему, можно обойтись обычным динамическим массивом. Так что ассемблер высокого уровня рулит, писать на чистом ассме не слишком эффективно, особенно если надо потом портировать код в С/С++. Тут и выручает ассемблер типа UASM, исходники в наличии, так что под свои нужды доработать напильником не проблема. ЗЫ А g_alive это имитация инлайн метода С++, жив ли объект. В С++ выглядит так. if (npc && npc.g_alive() ) ... Но на МАСМе это не работает, а вот на UASM работает, даже если g_alive просто функция. Так что UASM форева! ...в конце концов, важен лишь, машинный код. СТАЛКЕР только для ПК! Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 7 Июня 2018 Поделиться Опубликовано 7 Июня 2018 Ну, это явно кто-то извращался. Именно с целью добиться максимальной нечитаемости. Но на масме видали извращения и хуже. Например, самомодификацию кода по ходу выполнения. А вот оптимизация - чтобы ее сделать для современного процессора, нам просто ни кто не скажет, как. Через сколько команд можно повторно обращаться к тому же регистру на i3 ? А на ip5 ? Каково максимальное смещение для j* и одинаково ли оно для всех ? После какой команды это j* можно делать, а после какой - лучше вставить лишний nop ? P.S. И что, синтаксис обычного, не приплющенного c студия уже не позволяет ? Если так, пора уже, однако, делать нормальный мейкфайл для gcc, и переползать под него. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
НаноБот 740 Опубликовано 7 Июня 2018 Поделиться Опубликовано 7 Июня 2018 Кстати, я ещё AddCode* написал именно на МАСМ, т.к. посчитал что так будет быстрей, естественно использовал HLL(команды высокого уровня). Когда портировал код на С, то пришлось помучится из-за неявных преобразований, при этом проект собирается только VS C++, на Pelles C собирать не хочет**. Так что ассме кодить надо, хотя бы потому, что, на нем быстрей выходит чем на С/С++. Вот такой парадокс. * - утилита для добавления своего кода в целевой файл. Поддерживает изменения адресов релокаций, добавляет секцию данных. Может генерировать файл addr.inc. В дальнейшим возможно будет добавлены другие возможности. ** - так что развивать утилиту на С/С++ не вижу смысла. Так что проекты на макроассемблере высокого уровня могут конкурировать с С/С++. ...в конце концов, важен лишь, машинный код. СТАЛКЕР только для ПК! Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 7 Июня 2018 Поделиться Опубликовано 7 Июня 2018 Да как бы я и текстовые редакторы на micro-11 писал, было дело, с поддержкой мультиязычности и G-кода... Не считая всякого дискового и сетевого. (micro-11 - это упрощенная версия MACRO-11, для LSI/PDP и наших к1801). Но, в какой-то момент становится утомительно, а для современных, повторюсь, руками нормальную оптимизацию не сделать. Ну и библиотеки наработаны в основном для сей. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
buffy 4 Опубликовано 7 Июня 2018 Поделиться Опубликовано 7 Июня 2018 16 минут назад, НаноБот сказал: Так что ассме кодить надо, хотя бы потому, что, на нем быстрей выходит чем на С/С++. Вот такой парадокс. Тут всё зависит от потребностей: хотите программы, которые будут эргономичные и выполнять только то, что вы напишете - кодьте на асме, хотите программы, которые будут читабельные и понятные всем - используйте другой язык. А парадокса, смелюсь предположить, никакого нет, т.к, когда вы пишите на асме, вы получаете, только то, что написали, когда вы пишете на, к примеру, cpp компилятор может заменить некоторые выражения на более простые\сложные. Правда, самому увидеть не приходилось - знаю сам факт. Ссылка на комментарий
НаноБот 740 Опубликовано 7 Июня 2018 Поделиться Опубликовано 7 Июня 2018 (изменено) @buffy, Кодить низкоуровнено и понятно, можно и на С++, просто не используйте всякий хлам вроде std, вот так, как показано в этом коде. Сейчас я пытаюсь от компилировать код сверху, сначала пытался VS2010, не получилось, т.к. это С+11, 2010 слишком стар, сейчас пытаюсь VS2017, конечно не без проблем, студия тут же запросила обновление Microsoft.Windows.81SDK (181 МБ), т.е. ей мало несколько гигабайт, кажется 3 скачал. Спрашивается на кой оно надо, это просто чудовище, мрак полный, а всё индусы, которым платят за объём кода, точней политика оплаты рукой-водителей мракософта. Мракософт корпорация зла. ЗЫ ХАХХАХА код всё равно не компилируется, #include <stdlib.h> не может открыть файл. Мда уж. Кстати, этот код с хабра, консольное приложение. Источник. https://habr.com/post/216449/ ЗЫЫ А понял, надо установить платформу х64. ЗЫЫЫ Файл создан, но весит 59 кб, на асме такой же код, весил бы 2-3 кб максимум. И создать его бы не было проблемы. Почти столько же по времени. ЗЫЫЫЫ Не, однозначно, деградируют программисты, деградирует общество. Изменено 7 Июня 2018 пользователем НаноБот 1 1 1 1 ...в конце концов, важен лишь, машинный код. СТАЛКЕР только для ПК! Ссылка на комментарий
buffy 4 Опубликовано 8 Июня 2018 Поделиться Опубликовано 8 Июня 2018 @НаноБот, ёшкин кот;) вы наверное понимаете то, что ни один нормальный программист не будет писать на асме только для того, чтобы вывести надпись "Hello World"?) Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 8 Июня 2018 Поделиться Опубликовано 8 Июня 2018 Вот для отправить в ./dev/stdout "Hello World !" или типа того - асм не лишен смысла. Хотя сейчас есть awk, да и тот же LUA. В человеческих системах. Для инопланетян там же есть perl. 1 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Malandrinus 615 Опубликовано 9 Июня 2018 Поделиться Опубликовано 9 Июня 2018 НаноБот, Quote Мне не нравится С++, особенно С++11 и более новые редакции, =) "Вы просто не умеете их готовить" (C) Quote g_alive это имитация инлайн метода С+ Препроцессор (а ты говоришь о макросе препроцессора) - это средство времени ДО компиляции. Он берёт твой текст и преобразует его в другой текст, который затем уже и компилируется. Препроцессор по определению не делает ничего другого. Поэтому твоё пожелание, чтобы g_alive работал во время исполнения - заведомо некорректное. Этот макрос развернётся в что-то другое до того, как код вообще будет скомпилирован и уж всяко до исполнения. Инлайн-функции же работают совсем иначе. Инлайн функции - это конструкции времени компиляции, они учитывают контекст (своё окружение) а также все правила вызова функций. Когда ты имеешь дело с препроцессором, первый вопрос - хорошо ли ты понимаешь, что конкретно он делает. Без этого его использование чревато последствиями, поскольку ты видишь у себя один код, а реально компилируется что-то другое. Судя по всему, ты не до конца его понимаешь. Это нормально, препроцессор штука мутная, в случае с ассемблерами вообще не сильно стандартизированная и весьма специфичная для каждой конкретной версии и производителя, и именно поэтому его принято избегать. Quote всякий хлам вроде std Quote на асме такой же код, весил бы 2-3 кб максимум. И создать его бы не было проблемы. Почти столько же по времени. Я бы посмотрел, как ты написал бы на ассемблере парсер формул в 40 строк за пару часов (хотя наверняка этот код занял даже меньше). Dennis_Chikin, Quote Ну, это явно кто-то извращался. Именно с целью добиться максимальной нечитаемости Да нормальный код же! Ничего нечитаемого. И насчёт С++11 там ничего такого запредельного нет. Вполне можно было бы обойтись обычными указателями на функции, но и всё. К собственно читаемости алгоритма это никакого отношения не имеет. Quote А вот оптимизация - чтобы ее сделать для современного процессора, нам просто ни кто не скажет, как Есть полная официальная документация на каждый процессор, в том числе и насчёт оптимизации. Другое дело, что это весьма пухлый документ для профильных специалистов, собственно создателей компиляторов и библиотек низкого уровня. Их же для того и пишут, чтобы каждому прикладнику не нужно было вникать во все эти детали. Для вас стараются, а вы нос воротите =) Ну и не надо забывать про разные платформы. Код на ассемблере будет работать на конкретной платформе. Код на языке высокого уровня будет работать везде, где есть соответствующий компилятор/интерпретатор. Quote синтаксис обычного, не приплющенного c студия уже не позволяет ? Всё позволяет. Вообще, Мелкософт много в чём можно упрекнуть, но их С/С++ компиляторы - одни из лучших и с каждой версией становятся только лучше. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
abramcumner 1 146 Опубликовано 9 Июня 2018 Поделиться Опубликовано 9 Июня 2018 4 минуты назад, Malandrinus сказал: и с каждой версией становятся только лучше. Ну я бы так не сказал. с 15.5 до 15.6.5(а это в районе года) компилятор был сломан: выдавал ICE на float a = powf(s, 128); c 15.7 до 15.7.2 снова был сломан(в районе месяца): что-то с шаблонами. Каждая минорная версия что-нибудь ломает Ссылка на комментарий
buffy 4 Опубликовано 9 Июня 2018 Поделиться Опубликовано 9 Июня 2018 (изменено) 1 час назад, Malandrinus сказал: Я бы посмотрел, как ты написал бы на ассемблере парсер формул Но всё же неприятно, что программа, которая выводит какую-то надпись, весит 60кб. Изменено 9 Июня 2018 пользователем buffy Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 9 Июня 2018 Поделиться Опубликовано 9 Июня 2018 @Malandrinus, РЕДАКТОР с поддержкой формул был написан. А также поддержкой сетевой работы, станков с ЧПУ, и со сжатием. В одном флаконе. Правда, в три руки, и за пару лет. С другой стороны, писалось студиозусами, в свободное от зарабатывания на кусок хлеба с икрой время. 1801вм1, 4 кило памяти, 512x256 8 цветов видео. Отдельно существовала читалка для готовых текстов. Полтора кило размером, функция сборки текста из нескольких кусков. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
НаноБот 740 Опубликовано 17 Июня 2018 Поделиться Опубликовано 17 Июня 2018 (изменено) Вот код на ассемблере UASM Скрытый текст ;========================================================================= ; Консольное утилита для вычисления выражений ; Для UASM 2.46.10.0 ; Создан: 9.06.2018 г. 20:30 ; Изменения: 10.06.2018 г. 20:00 ; (c) NanoBot ;========================================================================= __MINIMAL_SIZE__ equ <> ; оптимизация на минимальный размер! .686 .XMM .model flat, stdcall option casemap:none include f:\masm32\include\windows.inc include f:\masm32\include\user32.inc include f:\masm32\include\kernel32.inc include f:\masm32\include\masm32.inc include f:\masm32\include\msvcrt.inc include f:\masm32\macros\macros.asm includelib f:\masm32\lib\user32.lib includelib f:\masm32\lib\kernel32.lib includelib f:\masm32\lib\masm32.lib includelib f:\masm32\lib\msvcrt.lib __getmainargs PROTO C :ptr, :ptr, :ptr, :dword, :ptr GetStartupInfoA PROTO stdcall :ptr STARTUPINFOA main PROTO C argc:dword, argv:ptr, environ:ptr ;========================= MACROSES ========================= LABEL_EXPR equ 1b ; метка кода MEM_EXPR equ 10b ; память IMM_EXPR equ 100b ; непосредственное выражение DIRECT_ADDR equ 1000b ; прямая адресация памяти REG_EXPR equ 10000b ; регистр VALID_REF equ 100000b ; валидное выражение MEM_SS_EXPR equ 1000000b ; память относительно SS регистра EXTER_LABEL_EXPR equ 10000000b ; внешняя метка VIMM_EXPR equ (VALID_REF OR IMM_EXPR) ; align_proc MACRO IFDEF __MINIMAL_SIZE__ align 1 ELSE align 16 ENDIF ENDM align_data MACRO IFDEF __MINIMAL_SIZE__ align 1 ELSE align 4 ENDIF ENDM @MEMSET MACRO Buf:req, value:req, count:req LOCAL pBuf push edi IF @InStr(1, <&Buf>, <&>) EQ 1 pBuf equ @SubStr(<&Buf>, 2) IF ((OPATTR pBuf) AND DIRECT_ADDR) OR ((OPATTR pBuf) AND LABEL_EXPR) mov edi, offset pBuf ELSE lea edi, pBuf ENDIF ELSEIFDIFI <Buf>, <edi> mov edi, Buf ENDIF IF value EQ 0 xor eax, eax ELSEIFDIFI <value>,<eax> mov eax, value ENDIF mov ecx, (count+3)/4 ; count - bytes rep stosd pop edi EXITM <> ENDM CVIRTUAL MACRO name_method:REQ, langType:REQ, retType:REQ, protoDef:VARARG LOCAL sz1, sz2 pDef CATSTR <TYPEDEF PROTO >,<&langType&>,< (&retType&)> IFNB <protoDef> pDef CATSTR pDef, <, >, <&protoDef> ENDIF IFDEF curClass sz2 CATSTR <_>, curClass, <_&name_method> ;; _curClass_method ELSE sz2 CATSTR <_>, <_&name_method> ENDIF % &sz2 &pDef ;; % echo &sz2 &pDef % sz1 typedef PTR &sz2 % name_method sz1 ? ENDM ;============================================================= char typedef byte ;double typedef real8 true equ 1 false equ 0 MAX_STACK equ 128 stOperation struct ; (sizeof = 8 bytes) CVIRTUAL func, <FASTCALL>, <VOIDARG>, a:ptr real8, b:ptr real8 priority sdword ? stOperation ends .data ;---------------------------------------------------------------------------- .code ; СТАРТОВЫЙ КОД mainCRTStartup proc C local argc:dword, argv:LPVOID, environ:LPVOID, _si:STARTUPINFOA mov _si.cb, sizeof STARTUPINFOA invoke GetStartupInfoA, addr _si invoke __getmainargs, addr argc, addr argv, addr environ, 0, addr _si invoke main, argc, argv, environ invoke ExitProcess, eax mainCRTStartup endp ;---------------------------------------------------------------------------- align_proc _add proc FASTCALL (VOIDARG) a:ptr real8, b:ptr real8 ; a equ ecx, b equ edx fld real8 ptr [a] fadd real8 ptr [b] fstp real8 ptr [a] ret _add endp align_proc _sub proc FASTCALL (VOIDARG) a:ptr real8, b:ptr real8 fld real8 ptr [a] fsub real8 ptr [b] fstp real8 ptr [a] ret _sub endp align_proc _mul proc FASTCALL (VOIDARG) a:ptr real8, b:ptr real8 fld real8 ptr [a] fmul real8 ptr [b] fstp real8 ptr [a] ret _mul endp align_proc _div proc FASTCALL (VOIDARG) a:ptr real8, b:ptr real8 fld real8 ptr [a] fdiv real8 ptr [b] fstp real8 ptr [a] ret _div endp align_proc main proc C argc:dword, argv:ptr, environ:ptr local level:dword, EndPtr:ptr char, stack_oper@end:dword local stack_value[MAX_STACK]:real8, stack_oper[MAX_STACK]:stOperation local func_token[256]:stOperation order = 2 printf("Calculator expression.\n") lea edi, func_token ASSUME edi:ptr stOperation, ebx:ptr char ;обнулим массив func_token @MEMSET (edi, 0, sizeof func_token) lea edi, [edi+'*'*8] mov [edi+'+'*8-'*'*8].func, offset _add mov [edi+'-'*8-'*'*8].func, offset _sub mov [edi+'*'*8-'*'*8].func, offset _mul mov [edi+'/'*8-'*'*8].func, offset _div or [edi+'+'*8-'*'*8].priority, 1 or [edi+'-'*8-'*'*8].priority, 1 or [edi+'*'*8-'*'*8].priority, 2 or [edi+'/'*8-'*'*8].priority, 2 mov level, ecx ;удалим пробелы ASSUME esi:ptr char mov eax, argv mov ebx, [eax+1*4] push ebx .for (esi=ebx ::ebx++, esi++) .while ([esi]==' ' || [esi]==9) inc esi .endw mov al, [esi] mov [ebx], al .break .if (!al) .endfor pop ebx ASSUME esi:ptr real8 lea esi, stack_value[-8] ; lea edi, stack_oper[-8] ; mov stack_oper@end, edi ;mov ebx, CSTR("18/(-7-(1+1))*3-(2+(1-2))/10.5*(10*10)") ;// для отладки в IDA Pro .while (true) .for (:[ebx]=='(':ebx++) add level, order .endfor invoke crt_strtod, ebx, addr EndPtr add esi, 8 mov ebx, EndPtr fstp [esi] .for (:[ebx]==')':ebx++) sub level, order .endfor .if (![ebx]) ;// строка закончилась .for (:edi>stack_oper@end: edi-=8, esi-=8); stack@dec (edi), stack@dec (esi) invoke [edi].func, addr [esi-8], addr [esi] .endfor mov edx, level sar edx, 1 ;/=order .if (!edx) mov edx, argv printf("%s = %.10f\n", [edx+1*4], [esi]) .else push edx .if (sdword ptr edx>0) ;printf("There is no closing parentheses: %d\n", edx) push CSTR("There is no closing parentheses: %d",0Dh,0Ah) .else ;printf("There is no opening parentheses: %d\n", edx) push CSTR("There is no opening parentheses: %d",0Dh,0Ah) .endif call crt_printf add esp, 8 .endif xor eax, eax ret .endif movzx edx, [ebx] mov eax, func_token[edx*8].priority ;eax - priority add eax, level .for (:edi>stack_oper@end && [edi].priority >= eax: edi-=8, esi-=8); stack@dec (edi), stack@dec (esi) push eax invoke [edi].func, addr [esi-8], addr [esi] pop eax .endfor movzx edx, [ebx] mov ecx, func_token[edx*8].func .break .if(!ecx) add edi, 8 mov [edi].func, ecx mov [edi].priority, eax inc ebx .endw ASSUME ebx:nothing, edi:nothing, esi:nothing printf("unknown token '%c'\n", edx) xor eax, eax inc eax ret main endp end mainCRTStartup Скачать UASM http://www.terraspace.co.uk/uasm.html Батник Скрытый текст @echo off ..\..\..\uasm246_x86\bin\uasm32 /c /coff "calc.asm" ..\..\..\uasm246_x86\bin\polink /SUBSYSTEM:CONSOLE "calc.obj" if exist "calc.obj" del "calc.obj" pause Линкер polink позволяется создавать компактные файлы. В нашем случае всего 1.5 кб. А теперь С++. Скрытый текст // Консольное утилита для вычисления выражений (c) NanoBot #include <iostream> #define MAX_STACK 128 #define order 2 void __fastcall add(double *a, double *b) { *a += *b; } void __fastcall sub(double *a, double *b) { *a -= *b; } void __fastcall mul(double *a, double *b) { *a *= *b; } void __fastcall div(double *a, double *b) { *a /= *b; } int main(int argc, char** argv) { struct stOperation { void set(void (__fastcall *f)(double *,double *), int p) { this->func = f; this->prior = p; }; void (__fastcall *func)(double *a, double *b); int prior; } TokFunc[128], stack_oper[MAX_STACK], *spOper = &stack_oper[-1], *stack_oper_end = spOper; double stack_value[MAX_STACK], *spValue = &stack_value[-1]; int level=0, prior; memset(TokFunc, 0, sizeof(TokFunc)); TokFunc['+'].set(add, 1); TokFunc['-'].set(sub, 1); TokFunc['*'].set(mul, 2); TokFunc['/'].set(div, 2); printf("Calculator expression.\n"); for (char* p0 = argv[1], *p1 = p0; ; p0++, p1++) { while(*p1==' ' || *p1==9) ++p1; *p0 = *p1; if(!*p1) break; } for (char* pStr = argv[1]; ; ++pStr) { for (; *pStr == '('; level += order, ++pStr); *++spValue = strtod(pStr, &pStr); for (; *pStr == ')'; level -= order, ++pStr); if (!*pStr) break; // строка закончилась char token = !(*pStr&(~0x7F)) ? *pStr : 0; // ограничем токены кодами 0..127 prior = TokFunc[token].prior + level; for (; spOper>stack_oper_end && spOper->prior >= prior; spOper--, spValue--) spOper->func(&spValue[-1], &spValue[0]); auto f = TokFunc[token].func; if (!f) { printf("unknown token '%c'\n", *pStr); return 1; } (++spOper)->set(f, prior); } for (; spOper>stack_oper_end; spOper--, spValue--) spOper->func(&spValue[-1], &spValue[0]); if(!level) printf("%s = %.10f\n", argv[1], *spValue); else if((level/=order)>0) printf("There is no closing parentheses: %d\n", level); else printf("There is no opening parentheses: %d\n", level); return 0; } Весит 7.5 кб если использовать VS2010, с VS2017 весит 9.5 кб и не работает на ХР. Так что к чёрту std cout и другую хрень. В 09.06.2018 в 20:41, Malandrinus сказал: Код на ассемблере будет работать на конкретной платформе. Будет работать на конкретным процессоре. Это не очень актуально, ибо есть только х86 и х64, остальные меня не интересуют, в точности ARM. Изменено 17 Июня 2018 пользователем НаноБот ...в конце концов, важен лишь, машинный код. СТАЛКЕР только для ПК! Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти