Вопросы по макросам

Тема в разделе "WASM.BEGINNERS", создана пользователем Mikl___, 17 мар 2011.

  1. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.878
    1) Подскажите, как в MASM на макро написать подобие INVOKE (цепочка PUSH'ей раскручивающая с конца строки и CALL), сам INVOKE по ряду причин использовать не могу
    2) как используя макро IRPC можно анализировать по два символа, меня интересует, как в макрос, преобразующий ASCII-строку в UNICODE-строку
    Код (Text):
    1. du macro string
    2.     irpc c,<string>
    3.     if '&c' gt 127
    4.     db ('&c'- 0B0h),4
    5.     else
    6.     dw '&c'
    7.     endif
    8.     endm
    9.     dw 0
    10.     endm
    обнаружив, что '&c'=='\' -- впихнуть анализ '\t', '\n' и т.п.
     
  2. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    Вот когда-то давно писал, gl функций.
    Код (Text):
    1. option NOKEYWORD:<invoke>    ;это обязательно в начале исходника
    2. pushm MACRO args:VARARG
    3. TEX TEXTEQU <>
    4. address TEXTEQU <>
    5. FOR item,<args>
    6.     IF @SizeStr(<item>) GE 6
    7.         TEX SUBSTR <item>,1,4
    8.         address SUBSTR <item>, 6, @SizeStr(<item>) - 5
    9.         IFIDN TEX,<addr>
    10.             lea eax,address
    11.             push eax
    12.         ELSEIFIDN TEX,<ADDR>
    13.             lea eax,address
    14.             push eax
    15.         ELSEIFIDN TEX,<Addr>
    16.             lea eax,address
    17.             push eax
    18.         ELSE
    19.             push item
    20.         ENDIF
    21.     ELSE
    22.         push item
    23.     ENDIF
    24. ENDM
    25. ENDM
    26. cntstr  = 0
    27. push_psrt MACRO args:VARARG
    28. LOCAL labelic,callic,defstr
    29.     labelic CATSTR <locastr_>,@CatStr(%cntstr)
    30.     callic CATSTR <call >,labelic
    31.     %callic
    32. ;;  defstr CATSTR <db '>,<args>,<',0>
    33. ;;  %defstr
    34.     db args,0
    35.     labelic CATSTR labelic,<:>
    36.     %labelic
    37.     cntstr = cntstr+1
    38. ENDM
    39.  
    40. invoke MACRO a,args:VARARG
    41. txt TEXTEQU <>
    42. IsFloat     TEXTEQU <>
    43. IsAddr  TEXTEQU <>
    44. %   FOR item, <args>
    45.         txt CATSTR <item>,<!,>,txt
    46.     ENDM
    47.     txt SUBSTR  txt, 1, @SizeStr( %txt ) - 1
    48. %   FOR item, <txt>
    49.         IsFloat SUBSTR <item>,1,1
    50.         IFIDN IsFloat,<'>
    51.             push_psrt item
    52.         ELSEIFIDN IsFloat,<0>
    53.             IF @SizeStr(item) GE 3
    54.                 IsFloat SUBSTR <item>,2,1
    55.                 IFIDN IsFloat,<.>
    56.                     db 68h
    57.                     REAL4 item
    58.                 ELSE
    59.                     push item
    60.                 ENDIF
    61.             ELSE
    62.                 push item
    63.             ENDIF
    64.         ELSEIFIDN IsFloat,<1>
    65.             IF @SizeStr(item) GE 3
    66.                 IsFloat SUBSTR <item>,2,1
    67.                 IFIDN IsFloat,<.>
    68.                     db 68h
    69.                     REAL4 item
    70.                 ELSE
    71.                     push item
    72.                 ENDIF
    73.             ELSE
    74.                 push item
    75.             ENDIF
    76.         ELSEIFIDN IsFloat,<2>
    77.             IF @SizeStr(item) GE 3
    78.                 IsFloat SUBSTR <item>,2,1
    79.                 IFIDN IsFloat,<.>
    80.                     db 68h
    81.                     REAL4 item
    82.                 ELSE
    83.                     push item
    84.                 ENDIF
    85.             ELSE
    86.                 push item
    87.             ENDIF
    88.         ELSEIFIDN IsFloat,<3>
    89.             IF @SizeStr(item) GE 3
    90.                 IsFloat SUBSTR <item>,2,1
    91.                 IFIDN IsFloat,<.>
    92.                     db 68h
    93.                     REAL4 item
    94.                 ELSE
    95.                     push item
    96.                 ENDIF
    97.             ELSE
    98.                 push item
    99.             ENDIF
    100.         ELSEIFIDN IsFloat,<4>
    101.             IF @SizeStr(item) GE 3
    102.                 IsFloat SUBSTR <item>,2,1
    103.                 IFIDN IsFloat,<.>
    104.                     db 68h
    105.                     REAL4 item
    106.                 ELSE
    107.                     push item
    108.                 ENDIF
    109.             ELSE
    110.                 push item
    111.             ENDIF
    112.         ELSEIFIDN IsFloat,<5>
    113.             IF @SizeStr(item) GE 3
    114.                 IsFloat SUBSTR <item>,2,1
    115.                 IFIDN IsFloat,<.>
    116.                     db 68h
    117.                     REAL4 item
    118.                 ELSE
    119.                     push item
    120.                 ENDIF
    121.             ELSE
    122.                 push item
    123.             ENDIF
    124.         ELSEIFIDN IsFloat,<6>
    125.             IF @SizeStr(item) GE 3
    126.                 IsFloat SUBSTR <item>,2,1
    127.                 IFIDN IsFloat,<.>
    128.                     db 68h
    129.                     REAL4 item
    130.                 ELSE
    131.                     push item
    132.                 ENDIF
    133.             ELSE
    134.                 push item
    135.             ENDIF
    136.         ELSEIFIDN IsFloat,<7>
    137.             IF @SizeStr(item) GE 3
    138.                 IsFloat SUBSTR <item>,2,1
    139.                 IFIDN IsFloat,<.>
    140.                     db 68h
    141.                     REAL4 item
    142.                 ELSE
    143.                     push item
    144.                 ENDIF
    145.             ELSE
    146.                 push item
    147.             ENDIF
    148.         ELSEIFIDN IsFloat,<8>
    149.             IF @SizeStr(item) GE 3
    150.                 IsFloat SUBSTR <item>,2,1
    151.                 IFIDN IsFloat,<.>
    152.                     db 68h
    153.                     REAL4 item
    154.                 ELSE
    155.                     push item
    156.                 ENDIF
    157.             ELSE
    158.                 push item
    159.             ENDIF
    160.         ELSEIFIDN IsFloat,<9>
    161.             IF @SizeStr(item) GE 3
    162.                 IsFloat SUBSTR <item>,2,1
    163.                 IFIDN IsFloat,<.>
    164.                     db 68h
    165.                     REAL4 item
    166.                 ELSE
    167.                     push item
    168.                 ENDIF
    169.             ELSE
    170.                 push item
    171.             ENDIF
    172.         ELSEIFIDN IsFloat,<->
    173.             IF @SizeStr(item) GE 4
    174.                 IsFloat SUBSTR <item>,2,1
    175.                 IFIDN IsFloat,<0>
    176.                     IsFloat SUBSTR <item>,3,1
    177.                     IFIDN IsFloat,<.>
    178.                         db 68h
    179.                         REAL4 item
    180.                     ELSE
    181.                         push item
    182.                     ENDIF
    183.                 ELSEIFIDN IsFloat,<1>
    184.                     IsFloat SUBSTR <item>,3,1
    185.                     IFIDN IsFloat,<.>
    186.                         db 68h
    187.                         REAL4 item
    188.                     ELSE
    189.                         push item
    190.                     ENDIF
    191.                 ELSEIFIDN IsFloat,<2>
    192.                     IsFloat SUBSTR <item>,3,1
    193.                     IFIDN IsFloat,<.>
    194.                         db 68h
    195.                         REAL4 item
    196.                     ELSE
    197.                         push item
    198.                     ENDIF
    199.                 ELSEIFIDN IsFloat,<3>
    200.                     IsFloat SUBSTR <item>,3,1
    201.                     IFIDN IsFloat,<.>
    202.                         db 68h
    203.                         REAL4 item
    204.                     ELSE
    205.                         push item
    206.                     ENDIF
    207.                 ELSEIFIDN IsFloat,<4>
    208.                     IsFloat SUBSTR <item>,3,1
    209.                     IFIDN IsFloat,<.>
    210.                         db 68h
    211.                         REAL4 item
    212.                     ELSE
    213.                         push item
    214.                     ENDIF
    215.                 ELSEIFIDN IsFloat,<5>
    216.                     IsFloat SUBSTR <item>,3,1
    217.                     IFIDN IsFloat,<.>
    218.                         db 68h
    219.                         REAL4 item
    220.                     ELSE
    221.                         push item
    222.                     ENDIF
    223.                 ELSEIFIDN IsFloat,<6>
    224.                     IsFloat SUBSTR <item>,3,1
    225.                     IFIDN IsFloat,<.>
    226.                         db 68h
    227.                         REAL4 item
    228.                     ELSE
    229.                         push item
    230.                     ENDIF
    231.                 ELSEIFIDN IsFloat,<7>
    232.                     IsFloat SUBSTR <item>,3,1
    233.                     IFIDN IsFloat,<.>
    234.                         db 68h
    235.                         REAL4 item
    236.                     ELSE
    237.                         push item
    238.                     ENDIF
    239.                 ELSEIFIDN IsFloat,<8>
    240.                     IsFloat SUBSTR <item>,3,1
    241.                     IFIDN IsFloat,<.>
    242.                         db 68h
    243.                         REAL4 item
    244.                     ELSE
    245.                         push item
    246.                     ENDIF
    247.                 ELSEIFIDN IsFloat,<9>
    248.                     IsFloat SUBSTR <item>,3,1
    249.                     IFIDN IsFloat,<.>
    250.                         db 68h
    251.                         REAL4 item
    252.                     ELSE
    253.                         push item
    254.                     ENDIF
    255.                 ELSE
    256.                     push item
    257.                 ENDIF              
    258.             ELSE
    259.                 push item
    260.             ENDIF          
    261.         ELSE       
    262.             pushm item
    263.         ENDIF
    264.     ENDM
    265.     call a
    266. ENDM
     
  3. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.878
    s_d_f
    Огромное спасибо!
     
  4. LShadow77

    LShadow77 New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2010
    Сообщения:
    36
    Существует директива IFIDNI, которая нечувствительна к регистру.

    Я для себя в своё время написал макробиблиотеку с весьма продвинутыми макросами, в частности для работы с UNICODE. Вот простой пример программы, использующеё эти макросы:
    Код (Text):
    1.         .386p
    2.         .model    flat,stdcall
    3.         include   windows.inc
    4.         include   kernel32.inc
    5.         include   kdvbase.inc  ;моя макробиблиотека
    6.  
    7.         includelib kernel32.lib
    8.  
    9.         ENCODING  "utf8"  ;указываем кодировку этого текста
    10.                             ;для корректного отображения кириллицы
    11.                             ;если текст набран в DOS-кодировке,
    12.                             ;то нужно указать "cp866", также заложил
    13.                             ;возможность других кодовых таблиц
    14.  
    15.         .data
    16. wszUni  dw        L("Непосредственно объявленная UNICODE-строка\n"),0
    17.                   ;макрос L() для непосредственного объявления строки UNICODE
    18.  
    19.         .code
    20. Start   proc
    21.         invoke    MessageBoxW, 0,WSZ("ПРЕВЕД МЕДВЕД\x31\r\n"+)\
    22.                                  WSZ("Новая строка :)"),\
    23.                                  WSZ("Сообщение в UNICODE"),MB_OK
    24.         invoke    MessageBoxW, 0,offset wszUni,\
    25.                                  WSZ("Сообщение в UNICODE"),MB_OK
    26.                   ;макрос WSZ() для объявления строки UNICODE "по ходу",
    27.                   ;строка объявляется только один раз (используется хеширование),
    28.                   ;макрос возвращает строчку <offset Name>, где Name - хэш-имя строки
    29.  
    30.         invoke    ExitProcess,0
    31. Start   endp
    32.         end       Start
    Тут лишь очень малая часть макросов из всех, которые находятся в kdvbase.inc.
    Вот думаю, выкладывать ли это в сеть...
     
  5. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.624
    Адрес:
    Russia
    Mikl___
    имхо --- не пишите инвоке, пишите лучше для каждой макрос вызова
     
  6. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.878
    Замена INVOKE
    Код (Text):
    1. .586
    2. .model flat
    3. include windows.inc
    4. includelib user32.lib
    5. extern _imp__MessageBoxA@16:dword
    6. ;-------------------------------------------------------------------
    7. OPTION NOKEYWORD: <invoke>
    8. invoke MACRO Fn,args:VARARG
    9. LOCAL txt,arg
    10. ;меняем порядок аргументов на обратный, каждый аргумент разделяем запятой
    11.     txt TEXTEQU <>;инициируем переменную txt как пустую строку
    12.     IRP arg,<args>;директива IRP делает одну копию указанных операторов
    13. ;для каждого из параметров, входящих в стоящий в угловых скобках список
    14.     txt CATSTR <arg>, <!,>, txt;"склеиваем" новую строку аргументов
    15. ;оператор ! указывает, что указанный "символ" нужно трактовать именно, как
    16. ;литеральный, для того, чтобы запятая воспринемалась не как разделитель
    17. ;операторов, а как символ (!, = ",")
    18.     ENDM
    19. %   IRP arg,<txt>;оператор % используется в тех случаях, когда нужно
    20. ;в макрос передать результат выражения
    21.     push arg; PUSH'им каждый аргумент в порядке обратном указанному
    22.     ENDM
    23.     call _imp__&Fn;оператор & указывает на границу формального параметра
    24. ENDM
    25. ;----------------------------------------------------------------------
    26. .code
    27. start:  invoke MessageBoxA@16, eax, offset MsgBoxText, offset MsgCaption,\
    28.     MB_OK or MB_ICONASTERISK
    29.     retn
    30. MsgCaption      db "Iczelion Tutorial #2:MessageBox",0
    31. MsgBoxText      db "Win32 Assembly with masm is Great!",0
    32. end start
     
  7. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.878
    макрос, преобразующий ASCII-строку в UNICODE-строку в MASM
    Код (Text):
    1. du  macro string
    2. local bslash
    3. bslash = 0
    4.     irpc c,<string>
    5.     if bslash eq 0
    6.         if '&c' eq "/"
    7.             bslash = 1
    8.         elseif '&c'gt 127
    9.         db ('&c'- 0B0h),4;; кириллица
    10.         else
    11.         dw '&c';; латиница
    12.         endif
    13.     else
    14.            bslash = 0
    15.            if '&c' eq "n";; управляющие символы
    16.            DW 0Dh,0Ah
    17.            elseif '&c' eq "/"
    18.            dw '/'
    19.            elseif '&c' eq "r"
    20.            dw 0Dh
    21.            elseif '&c' eq "l"
    22.            dw 0Ah
    23.            elseif '&c' eq "s"
    24.            dw 20h
    25.            elseif '&c' eq "c"
    26.            dw 3Bh
    27.            elseif '&c' eq "t"
    28.            dw 9
    29.        endif
    30.     endif
    31.     endm
    32.     dw 0;; ноль, завершающий UNICODE-строку
    33.     endm
     
  8. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    Локальные макро-переменные не следует использовать без необходимости.
    Вторую строку лучше убрать.
    Код (Text):
    1. local bslash
     
  9. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.878
    s_d_f
    можно конечно bslash объявить как глобальную константу, но ведь макрос DU может быть вызван из нескольких мест, local bslash сделана по подобию Strings.mac by Four-F (см. STRINGA MACRO)
     
  10. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    Это легко проверяется на практике. Никаких проблем не будет. Локальные полезны только в редких случаях при рекурсии.
    Просто у меня были проблемы именно из-за того что я слишком часто использовал LOCAL, без необходимости. Потом пришлось их удалять.
     
  11. LShadow77

    LShadow77 New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2010
    Сообщения:
    36
    Как я посмотрю, нормальные и надёжные макросы по UNICODE (и не только) никому не нужны. Жаль, а уже хотел было выложить...
     
  12. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.878
    LShadow77
    А вы ожидали голосования по поводу выкладывать или не выкладывать kdvbase.inc ?
    P.S. продолжая вашу мысль: и у меня, и у s_d_f макросы ненормальные и ненадёжные?
     
  13. LShadow77

    LShadow77 New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2010
    Сообщения:
    36
    Это ваша мысль и только ваша (я свою не продолжал)!
    А насчёт голосования, кстати, неплохая идея. Чем каждый ассемблерщик изобретал велосипед, не лучше было бы организовать конкурс макробиблиотек (моих, ваших, s_d_f и др. пользователей) и опубликовать лучшую на сайте?
     
  14. paralvic

    paralvic Пархоменко Александр Викторович

    Публикаций:
    0
    Регистрация:
    20 ноя 2010
    Сообщения:
    294
    Адрес:
    Нижний Новгород
    To Heap (в смысле До кучи ;)
    Код (Text):
    1. .586
    2. .model flat, stdcall    
    3. option casemap :none  
    4.  
    5. ; To get unicode support
    6. include     \masm32\macros\ucmacros.asm
    7.  
    8. include     \masm32\include\windows.inc
    9. include     \masm32\include\kernel32.inc
    10. includelib  \masm32\lib\kernel32.lib
    11.  
    12. include     \masm32\include\user32.inc
    13. includelib  \masm32\lib\user32.lib     
    14.  
    15. .data
    16. ; WSTR gets you a unicode string definition
    17. WSTR wstrTitle, "Hello"
    18. WSTR wstrMessage, "World"
    19.  
    20. .code
    21.  
    22. main:
    23.     invoke MessageBoxW, NULL, ADDR wstrMessage, ADDR wstrTitle, MB_OK
    24.  
    25.     invoke ExitProcess, eax
    26. end main