Я знаю что есть макрос у Fasm. И я им пользуюсь. Но как мне сделать такое и что бы в место этого подставить команды сопроцессора? Вот строчка x= 20*10/20+1. Как сделать именно такой вид строчки , а не через запятые (через зяпятые я такое могу сделать). И в макросе делать сравнения , если * то команда умножения fmulp, если / то команда fdiv. И так далее.
l_inc Потому что написать комплятор формул записанных в таком виде да ещё учитывающий приоритет операций на сильно убогом макроязыке fasma или masmа задачка исключительно для мазохизма Имхо что-то большее чем компиляция записей в обратной польской нотации (RPN) даже и пытаться сделать не стоит Ronniko Лучше уж написать полноценный модуль обработки формул на асме (не путать асм с макроязыком) или HiLevel языке а потом встроить его в сорцы fasmа или использовать в качестве препроцессора.
l_inc, как минимум потому что макрос вызывать надо: compute x=20*10/20+1 – вот так можно, если постараться. Y_Mur, макроязык фасма хоть и убогий, но такое сделать позволяет. В аттаче быстрое решение для +-/* с костылями, но и с приоритетами. Ronniko, присоеднияюсь к советующим писать на сях. Никакой выгоды от такой «компиляции» ассемблером нет. Если писать на ассемблере, то оптимизировать руками. Если на ассемблере неудобно, взять компилятор (хоть тот же tcc, который оптимизировать не умеет, и сгенерит примерно такой же код, что и макрос). А макросы подобные для забавы разве что.
Ronniko А ты случаем компилятор формул на макросах с вычислением констант во время компиляции не путаешь? GoldFinch прав - если хочется чтобы формулы "красиво" выглядели то используй Си, сила асма в возможности низкоуровневой оптимизации FPU вычислений, которую все языки высокого уровня делают весьма посредственно, и имхо это единственная достойная причина использовать асм в FPU вычислениях. Но сотворить приличный оптимизирующий компилятор FPU формул задача весьма непростая даже при наличии удобных языковых средств программирования, а уж тем более на макроязыке. Вот достаточно примитивные примеры ручной оптимизации FPU вычислений (вклиненные в него коментарии отражают текущее состояние FPU стека для удобства определения текущих номеров FPU регистров, что существенно повышает удобство написания FPU кода): Код (Text): .ELSEIF [wparam] == 0BBh ; ----- '+' ----- --- Увеличение --- FLD [GrW_DeltaHiScale] FLD [GrW_StepHiScale] ; deltaScale, StepScale FMUL [GrW_Scale] ; Scale*StepScale; [Matrix.m11] FLD [GrW_R8_Rect.y] FLD [GrW_R8_Rect.x] ; deltaScale, StepScale, Matrix.d_Y, Matrix.d_X FLD [GrW_R8_Rect.w] FLD [_1_div_2] FMUL ST(1), ST ; r_mX = R8_Rect.w / 2 FLD [GrW_R8_Rect.h] FMULP ST(1), ST ; r_mY = R8_Rect.h / 2 ; deltaScale, Scale*StepScale, Matrix.d_Y, Matrix.d_X, r_mX, r_mY FSUB ST, ST(3) ; deltaY = r_mY - Matrix.d_Y FMUL ST, ST(5) ; deltaY * deltaScale FADD ST, ST(3) ; deltaY * deltaScale + Matrix.d_Y FST [GrW_R8_Rect.y] FSTP [GrW_Matrix.d_Y] ; для GDI+ ; deltaScale, Scale*StepScale, Matrix.d_Y, Matrix.d_X, r_mX FSUB ST, ST(1) ; deltaX = r_mX - Matrix.d_X FMUL ST, ST(4) ; deltaX * deltaScale FADD ST, ST(1) ; deltaX * deltaScale + Matrix.d_X FST [GrW_R8_Rect.x] FSTP [GrW_Matrix.d_X] ; для GDI+ FCOMPP ; deltaScale, Scale*StepScale FST [GrW_Scale] ; Новый масштаб FST [GrW_Matrix.m11] ; для GDI+ FST [GrW_Matrix.m22] FLD1 FDIVRP ST(1), ST FSTP [GrW_ReScale] ; Новый обратный масштаб FSTP ST ;----------------------------------- ;..... ;----------------------------------- ; - - - Вспомогательная таблица значений - - - ; 2*y*w(y)*dy = 4*y*SQRT(R^2 - Y^2)*dy FLD [_4_0] FLD [R_console] FLD ST FMUL ST, ST ; R^2 FILD [N_Section_lines] FDIVP ST2, ST ; шаг: dy = R_console/N_Section_lines mov edi, [Section_prep] mov ecx, __N_Section_lines FLD ST1 ; dy FMUL ST3, ST ; 4*dy FMUL [_1_div_2] ; y0 = dy/2 ; 4*dy, dy, R_console^2, y @@: FST [edi].SECT_PREP.y ; сохранить y FLD ST FMUL ST, ST4 ; 4*Y*dy FLD ST1 ; Y FMUL ST, ST ; Y^2 FSUBR ST, ST3 ; R^2 - Y^2 FSQRT ; SQRT(R^2 - Y^2) FMULP ST1, ST ; 4*Y*SQRT(R^2 - Y^2) * dy (осталось только * Sigma(Epsilon(y))) FSTP [edi].SECT_PREP.prep ; сохранить 4*Y*SQRT(R^2 - Y^2) * dy FADD ST, ST2 ; y + dy add edi, sizeof SECT_PREP dec ecx jnz @B FCOMPP FCOMPP
В общем на сях это делать будет правильно. Но вот только сам макрос наверно тоже можно оптимизировать по своему усмотрению. А на сях там можно только общие опции компиляции указывать, оптимизация по размеру,по скорости, под определённый тип процессора.
s_d_f, на сях можно кодогенератор написать. А вот оптимизировать формулы фасмовыми макросами, когда у препроцессора даже целочисленная арифметика через как обычно, а ассемблер даже 3.14 * 2 вычислить самостоятельно не умеет – вот это уж точно занятие для мазохистов.
s_d_f CPU код Си компиляторы умеют оптимизировать более менее соизмеримо с ручным вариантом, с FPU дела обстоят гораздо хуже и причина как раз в сложности написания оптимизирующего FPU компилятора, поэтому всякие игры с "оптимизирующими" макросами в этом случае не более чем детские забавы.
Y_Mur Это не объяснение. Мазохизм — одно, а теоретическая возможность — другое. SFeLi Я что-то не понимаю, почему макросом не может быть x: Код (Text): macro x [.] { common match ==\.,. \{ irps \\.,\. \\{ display \\`\\. \\} \} } x = 20*10/20+1 Вполне себе нормально перечисляются символы.
l_inc Улыбнуло ) А не смущает что ТС явно хотел чтобы в переменную x занёсся результат вычислений? PS: Хотя есть подозрение что ТС не совсем представляет что же он на самом деле хочет )
SFeLi Y_Mur Все эти сложности прежде всего связаны с тем, что этим мало кто занимается вообще, но это не значит что они в принципе не решаемы. FPU код компиляторы плохо оптимизируют, и смысла большого улучшать там что-то нет. Уже давно рекомендуют пользовать скалярными SSE. CPU код оптимизируется, что вполне логично, без этого ничего не получится. Относиться к этому можно по разному, но выкручиваться здесь так или иначе придётся самостоятельно. Выбор здесь не большой, макрос или внешний препроцессор и везде мало не покажется.
Y_Mur Абсолютно не смущает. Например, делаем так: Код (Text): macro asComputationDestination symbol* { match .,symbol \{ macro \. [\\.] \\{ common match ==\\\.,\\. \\\{ irps \\\\.,\\\. \\\\{ display \\\\`\\\\. \\\\} \\\} \\} \} } asComputationDestination x x = 20*10/20+1 Внутри объявления x (т.е. внутри макроса common match ==\\\.,\\.) делаем передачу значения в оригинальную область памяти x. Здесь эту передачу не привёл, т.к. нужен результат вычислений. P.S. Со вложенностью переборщил. symbol ведь и так раскроется. Так что можно и так: Код (Text): macro asComputationDestination symbol* { macro symbol [\.] \{ common match ==\\.,\. \\{ irps \\\.,\\. \\\{ display \\\`\\\. \\\} \\} \} }