Как сделать SWITCH в fasm?

Тема в разделе "WASM.ASSEMBLER", создана пользователем hypers, 25 ноя 2006.

  1. hypers

    hypers New Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2006
    Сообщения:
    34
    Вот замутил несколько макросов - continue, continueif, break, breakif, JCOND.
    JCOND - это "инверсия" от макроса JNCOND в файле if.inc
    continue, continueif, break, breakif - используются внутри цикла while.
    Странно, в масме эти дериктивы есть а фасме нету!
    Теперь хотелось бы сделать SWITCH как в С++
    У кого есть какие соображения?

    Код (Text):
    1. ; Macroinstructions for HLL-style conditional operations
    2.  
    3. macro .continue
    4. {
    5.     jmp __WHILE
    6. }
    7.  
    8. macro .continueif [arg]
    9. {
    10.     JCOND   __WHILE,arg
    11. }
    12.  
    13. macro .break
    14. {
    15.     jmp __ENDW
    16. }
    17.  
    18. macro .breakif [arg]
    19. {
    20.     JCOND   __ENDW,arg
    21. }
    22.  
    23. macro JCOND label,v1,c,v2
    24. {
    25.     match any,c
    26.     \{
    27.         cmp v1,v2
    28.         j\#c label
    29.     \}
    30.     match ,c
    31.     \{
    32.         PARSECOND parsed@cond,v1
    33.         match cond,parsed@cond \\{ JCONDEXPR label,cond \\}
    34.     \}
    35. }
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Поиск по форуму фасма. Там несколько реализаций предлагалось.
     
  3. hypers

    hypers New Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2006
    Сообщения:
    34
    Нашёл. Кому интересно:
    http://board.flatassembler.net/topic.php?t=3768

    И почему Гриштар не соберёт все путёвые макросы в свой fasm... :/
     
  4. Avoidik

    Avoidik New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2004
    Сообщения:
    288
    Адрес:
    Russia
    hypers, потому что ему нафиг не нужен геморрой с вопросами почему не работает и как этим пользоваться
     
  5. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    hypers
    Avoidik прав. Плюс то, что макросы можешь менять как хочешь, да и препроцессор меняется. Нет смысла поддерживать старьё. По поводу выбранной тобой реализации - она не хорошая, использовать её лучше когда значения в case не очень отличаются друг от друга, иначе сгенерированная таблица будет слишком большой. Была другая, обычная, без таблицы.
     
  6. hypers

    hypers New Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2006
    Сообщения:
    34
    Согласен. А для чего вообще эта таблица?

    Не нашел.
     
  7. Yasha

    Yasha New Member

    Публикаций:
    0
    Регистрация:
    28 янв 2011
    Сообщения:
    1
    Предлагаю обсудить такой вариант
    Код (Text):
    1. macro switch var
    2. {
    3.         local tableval, tablejmp, done, size
    4.         if ~ var eq eax
    5.         mov eax,var
    6.         end if
    7.         mov     ecx, size
    8.         mov     edi, tableval
    9.         repne   scasd
    10.         not     ecx
    11.         jmp     dword [tablejmp + 4 * size + 4 * ecx]
    12.         tableval dd size dup ?
    13.         tablejmp dd size dup $
    14.         local   cnt
    15.         cnt = 0
    16.   macro case value
    17.   \{
    18.         virtual
    19.         dd $
    20.         load dest@case dword from $ - 4
    21.         end virtual
    22.         store   dword dest@case at tablejmp + cnt * 4
    23.         store   dword value at tableval + cnt * 4
    24.         cnt = cnt + 1
    25.   \}
    26.   macro break  \{ jmp done \}
    27.   macro finish@switch \{
    28.         done:
    29.         size = cnt
    30.   \}
    31. }
    32.  
    33. macro endswitch {
    34.   finish@switch
    35.   purge case,break,finish@switch
    36. }
    Строится список из указанных значений и список адресов, с помощью scasd ищется совпадение (что быстрее, чем цепочка jump'ов), осуществляется переход на соответствующий адрес. Если значение не найдено, осуществляется переход на последний case (надо же куда-то переходить)
    Использовать примерно так:
    Код (Text):
    1. switch [value]
    2. case 10h
    3.    ...
    4.   break
    5. case 202h
    6.    ...
    7.   break
    8. case 0
    9.    ...
    10. endswitch
     
  8. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.787