Хочу сделать в Fasm с помощью макроса вот такое x= 20*10/20+1

Тема в разделе "WASM.BEGINNERS", создана пользователем Ronniko, 12 окт 2010.

  1. Ronniko

    Ronniko New Member

    Публикаций:
    0
    Регистрация:
    8 ноя 2009
    Сообщения:
    21
    Я знаю что есть макрос у Fasm.
    И я им пользуюсь.
    Но как мне сделать такое и что бы в место этого подставить команды сопроцессора?
    Вот строчка x= 20*10/20+1.
    Как сделать именно такой вид строчки , а не через запятые (через зяпятые я такое могу сделать).
    И в макросе делать сравнения , если * то команда умножения fmulp, если / то команда fdiv.
    И так далее.
     
  2. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    Прямо чтобы так не получится. Но irps x,20*10/20+1 { display `x,0x0d,0x0a } даст тебе идею.
     
  3. Ronniko

    Ronniko New Member

    Публикаций:
    0
    Регистрация:
    8 ноя 2009
    Сообщения:
    21
    Спасибо iZzz32
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    iZzz32
    А почему "прямо чтобы так не получится"?
     
  5. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    l_inc
    Потому что написать комплятор формул записанных в таком виде да ещё учитывающий приоритет операций на сильно убогом макроязыке fasma или masmа задачка исключительно для мазохизма :) Имхо что-то большее чем компиляция записей в обратной польской нотации (RPN) даже и пытаться сделать не стоит ;)

    Ronniko
    Лучше уж написать полноценный модуль обработки формул на асме (не путать асм с макроязыком) или HiLevel языке а потом встроить его в сорцы fasmа или использовать в качестве препроцессора.
     
  6. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    Ronniko
    лучше пишите на Си
     
  7. SFeLi

    SFeLi Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    10 фев 2006
    Сообщения:
    6
    Адрес:
    Severodvinsk, Russia
    l_inc, как минимум потому что макрос вызывать надо: compute x=20*10/20+1 – вот так можно, если постараться.

    Y_Mur, макроязык фасма хоть и убогий, но такое сделать позволяет. В аттаче быстрое решение для +-/* с костылями, но и с приоритетами.

    Ronniko, присоеднияюсь к советующим писать на сях. Никакой выгоды от такой «компиляции» ассемблером нет. Если писать на ассемблере, то оптимизировать руками. Если на ассемблере неудобно, взять компилятор (хоть тот же tcc, который оптимизировать не умеет, и сгенерит примерно такой же код, что и макрос). А макросы подобные для забавы разве что.
     
  8. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Ronniko
    А ты случаем компилятор формул на макросах с вычислением констант во время компиляции не путаешь?

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

    Вот достаточно примитивные примеры ручной оптимизации FPU вычислений (вклиненные в него коментарии отражают текущее состояние FPU стека для удобства определения текущих номеров FPU регистров, что существенно повышает удобство написания FPU кода):
    Код (Text):
    1.   .ELSEIF [wparam] == 0BBh ;   ----- '+' ----- --- Увеличение ---
    2.     FLD [GrW_DeltaHiScale]
    3.     FLD [GrW_StepHiScale]
    4.     ; deltaScale, StepScale
    5.     FMUL  [GrW_Scale]   ; Scale*StepScale; [Matrix.m11]
    6.     FLD   [GrW_R8_Rect.y]
    7.     FLD   [GrW_R8_Rect.x]
    8.     ; deltaScale, StepScale, Matrix.d_Y, Matrix.d_X
    9.     FLD   [GrW_R8_Rect.w]
    10.     FLD   [_1_div_2]
    11.     FMUL  ST(1), ST ; r_mX = R8_Rect.w / 2
    12.     FLD   [GrW_R8_Rect.h]
    13.     FMULP ST(1), ST ; r_mY = R8_Rect.h / 2
    14.     ; deltaScale, Scale*StepScale, Matrix.d_Y, Matrix.d_X, r_mX, r_mY
    15.     FSUB  ST, ST(3) ; deltaY = r_mY - Matrix.d_Y
    16.     FMUL  ST, ST(5) ; deltaY * deltaScale
    17.     FADD  ST, ST(3) ; deltaY * deltaScale + Matrix.d_Y
    18.     FST   [GrW_R8_Rect.y]
    19.     FSTP  [GrW_Matrix.d_Y] ; для GDI+
    20.     ; deltaScale, Scale*StepScale, Matrix.d_Y, Matrix.d_X, r_mX
    21.     FSUB  ST, ST(1) ; deltaX = r_mX - Matrix.d_X
    22.     FMUL  ST, ST(4) ; deltaX * deltaScale
    23.     FADD  ST, ST(1) ; deltaX * deltaScale + Matrix.d_X
    24.     FST   [GrW_R8_Rect.x]
    25.     FSTP  [GrW_Matrix.d_X] ; для GDI+
    26.     FCOMPP
    27.     ; deltaScale, Scale*StepScale
    28.     FST    [GrW_Scale]  ; Новый масштаб
    29.     FST    [GrW_Matrix.m11] ; для GDI+
    30.     FST    [GrW_Matrix.m22]
    31.     FLD1
    32.     FDIVRP ST(1), ST
    33.     FSTP   [GrW_ReScale] ; Новый обратный масштаб
    34.     FSTP   ST
    35. ;-----------------------------------
    36. ;.....
    37. ;-----------------------------------
    38.    ; - - - Вспомогательная таблица значений - - -
    39.    ; 2*y*w(y)*dy = 4*y*SQRT(R^2 - Y^2)*dy
    40.    FLD  [_4_0]
    41.    FLD  [R_console]
    42.    FLD  ST
    43.    FMUL ST, ST      ; R^2
    44.    FILD  [N_Section_lines]
    45.    FDIVP ST2, ST    ; шаг: dy = R_console/N_Section_lines
    46.    mov edi, [Section_prep]
    47.    mov ecx, __N_Section_lines
    48.    FLD  ST1     ; dy
    49.    FMUL ST3, ST     ; 4*dy
    50.    FMUL [_1_div_2]  ; y0 = dy/2
    51.    ; 4*dy, dy, R_console^2, y
    52.    @@:
    53.      FST   [edi].SECT_PREP.y    ; сохранить y
    54.      FLD   ST
    55.      FMUL  ST, ST4  ; 4*Y*dy
    56.      FLD   ST1      ; Y
    57.      FMUL  ST, ST   ; Y^2
    58.      FSUBR ST, ST3  ; R^2 - Y^2
    59.      FSQRT      ; SQRT(R^2 - Y^2)
    60.      FMULP ST1, ST  ; 4*Y*SQRT(R^2 - Y^2) * dy (осталось только * Sigma(Epsilon(y)))
    61.      FSTP  [edi].SECT_PREP.prep ; сохранить 4*Y*SQRT(R^2 - Y^2) * dy
    62.      FADD  ST, ST2  ; y + dy
    63.      add edi, sizeof SECT_PREP
    64.      dec ecx
    65.    jnz @B
    66.    FCOMPP
    67.    FCOMPP
     
  9. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    В общем на сях это делать будет правильно.
    Но вот только сам макрос наверно тоже можно оптимизировать по своему усмотрению.
    А на сях там можно только общие опции компиляции указывать, оптимизация по размеру,по скорости,
    под определённый тип процессора.
     
  10. SFeLi

    SFeLi Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    10 фев 2006
    Сообщения:
    6
    Адрес:
    Severodvinsk, Russia
    s_d_f, на сях можно кодогенератор написать. А вот оптимизировать формулы фасмовыми макросами, когда у препроцессора даже целочисленная арифметика через как обычно, а ассемблер даже 3.14 * 2 вычислить самостоятельно не умеет – вот это уж точно занятие для мазохистов.
     
  11. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    s_d_f
    CPU код Си компиляторы умеют оптимизировать более менее соизмеримо с ручным вариантом, с FPU дела обстоят гораздо хуже и причина как раз в сложности написания оптимизирующего FPU компилятора, поэтому всякие игры с "оптимизирующими" макросами в этом случае не более чем детские забавы.
     
  12. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Y_Mur
    Это не объяснение. Мазохизм — одно, а теоретическая возможность — другое.
    SFeLi
    Я что-то не понимаю, почему макросом не может быть x:
    Код (Text):
    1. macro x [.] { common match ==\.,. \{ irps \\.,\. \\{ display \\`\\. \\} \} }
    2. x = 20*10/20+1
    Вполне себе нормально перечисляются символы.
     
  13. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    l_inc
    Улыбнуло :))
    А не смущает что ТС явно хотел чтобы в переменную x занёсся результат вычислений?

    PS: Хотя есть подозрение что ТС не совсем представляет что же он на самом деле хочет :))
     
  14. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    l_inc, ну разве только так, да)
     
  15. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    SFeLi
    Y_Mur
    Все эти сложности прежде всего связаны с тем, что этим мало кто занимается вообще, но это не значит что они в принципе не решаемы.

    FPU код компиляторы плохо оптимизируют, и смысла большого улучшать там что-то нет. Уже давно рекомендуют пользовать скалярными SSE. CPU код оптимизируется, что вполне логично, без этого ничего не получится.

    Относиться к этому можно по разному, но выкручиваться здесь так или иначе придётся самостоятельно.
    Выбор здесь не большой, макрос или внешний препроцессор и везде мало не покажется.
     
  16. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Y_Mur
    Абсолютно не смущает. Например, делаем так:
    Код (Text):
    1. macro asComputationDestination symbol* { match .,symbol \{ macro \. [\\.] \\{ common match ==\\\.,\\. \\\{ irps \\\\.,\\\. \\\\{ display \\\\`\\\\. \\\\} \\\} \\} \} }
    2.  
    3. asComputationDestination x
    4. x = 20*10/20+1
    Внутри объявления x (т.е. внутри макроса common match ==\\\.,\\.) делаем передачу значения в оригинальную область памяти x. Здесь эту передачу не привёл, т.к. нужен результат вычислений.

    P.S. Со вложенностью переборщил. symbol ведь и так раскроется. Так что можно и так:
    Код (Text):
    1. macro asComputationDestination symbol* { macro symbol [\.] \{ common match ==\\.,\. \\{ irps \\\.,\\. \\\{ display \\\`\\\. \\\} \\} \} }