Полезные макросы для MASM и TASM

Тема в разделе "WASM.ASSEMBLER", создана пользователем Jin X, 10 янв 2017.

  1. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Не претендую на создание чего-то нового и гениального, но макросы довольно полезные. Часть из того, что я сделал, уже делали другие. Тем не менее, большинство макросов придумано и сделано мною с нуля, остальной код переписан по-своему :)
    Вот эти макросы (полный вариант, только заголовки):
    Код (ASM):
    1. ;############################################
    2. ;##                                        ##
    3. ;##   -= EXTRA MACROSES (FULL EDITION) =-  ##
    4. ;##      МАКРОСЫ ДЛЯ MASM/TASM (16/32)     ##
    5. ;##             Полный вариант             ##
    6. ;##         [ v1.00 :: 09.01.2017 ]        ##
    7. ;##                                        ##
    8. ;##  (c) 2017 by Jin X (jin.x@sources.ru)  ##
    9. ;##           http://xk7.ru/p/a/i          ##
    10. ;##                                        ##
    11. ;############################################
    12. xmacro_ver = 100h ; версия данного файла (word: старший байт - целая часть, младший - дробная)
    13. ;-------------------------------------------------------------------------------
    14. @ equ <offset>
    15. $b equ <byte ptr>
    16. $w equ <word ptr>
    17. $d equ <dword ptr>
    18. $f equ <fword ptr>
    19. $q equ <qword ptr>
    20. $t equ <tbyte ptr>
    21. $s equ <short>
    22. $n equ <near>
    23. $f equ <far>
    24. ; Выполнение инструкций/директив/макросов, заданных одной строкой
    25. _ macro p1, p2, p3, p4, p5, p6, p7, p8, p9, p10
    26. ;-------------------------------------------------------------------------------
    27. ;-- УСЛОВНЫЕ МАКРОСЫ -----------------------------------------------------------
    28. ;-------------------------------------------------------------------------------
    29. ; Если cond, исполнить do1; иначе do0
    30. ifel macro cond:req, do1, do0
    31. ifdo equ <ifel>
    32. ifn equ <ife>
    33. ; Если НЕ cond, исполнить do1; иначе do0
    34. ifnel macro cond:req, do1, do0
    35. ifeel equ <ifnel>
    36. ; Если cond1, исполнить do1; иначе если cond2, исполнить do2; иначе do0
    37. ifelif macro cond1:req, do1, cond2:req, do2, do0
    38. ; ifdef id (если идентификатор определён), исполнить do1; иначе do0
    39. ifdefel macro id:req, do1, do0
    40. ; ifndef id (если идентификатор НЕ определён), исполнить do1; иначе do0
    41. ifndefel macro id:req, do1, do0
    42. ; ifb exp (если выражение пустое), исполнить do1; иначе do0
    43. ifbel macro exp, do1, do0
    44. ; Если выражение exp пустое или состоит из пробелов, исполнить do1; иначе do0
    45. ifbbel macro exp, do1, do0
    46. ; ifnb exp (если выражение НЕпустое), исполнить do1; иначе do0
    47. ifnbel macro exp, do1, do0
    48. ; Если выражение exp НЕпустое и НЕ состоит из пробелов, исполнить do1; иначе do0
    49. ifnbbel macro exp, do1, do0
    50. ; ifidn exp1, exp2 (если значения совпадают С учётом регистра символов), исполнить do1; иначе do0
    51. ifidnel macro exp1:req, exp2:req, do1, do0
    52. ; ifidni cond (если значения совпадают БЕЗ учёта регистра символов), исполнить do1; иначе do0
    53. ifidniel macro exp1:req, exp2:req, do1, do0
    54. ; ifidn exp1, exp2 (если значения различаются С учётом регистра символов), исполнить do1; иначе do0
    55. ifdifel macro exp1:req, exp2:req, do1, do0
    56. ; ifidni cond (если значения различаются БЕЗ учёта регистра символов), исполнить do1; иначе do0
    57. ifdifiel macro exp1:req, exp2:req, do1, do0
    58. ; Если cond1 или cond2 (условие cond2 проверяется только в том случае, если cond1 не выполнилось), исполнить do1; иначе do0
    59. iforel macro cond1:req, cond2:req, do1, do0
    60. ; Если cond1 и cond2 (условие cond2 проверяется только в том случае, если cond1 выполнилось), исполнить do1; иначе do0
    61. ifandel macro cond1:req, cond2:req, do1, do0
    62. ; Аналогично ifel, но условие подставляется слитно с if, например: ifelx <def debug>, <int 3>, nop
    63. ifelx macro cond:req, do1, do0
    64. ifx equ <ifelx>
    65. ; Аналогично ifnel, но условие подставляется слитно с if, например: ifnelx <def debug>, nop, <int 3>
    66. ifnelx macro cond:req, do1, do0
    67. ifeelx equ <ifnelx>
    68. ; Аналогично ifelif, но условия подставляются слитно с if, например: ifelifx <def debug>, <int 3>, <idn <spec>, <stosb>>, stosb, nop
    69. ifelifx macro cond1:req, do1, cond2:req, do2, do0
    70. ; Аналогично iforel, но условия подставляются слитно с if
    71. iforelx macro cond1:req, cond2:req, do1, do0
    72. ; Аналогично ifandel, но условия подставляются слитно с if
    73. ifandelx macro cond1:req, cond2:req, do1, do0
    74. ;-------------------------------------------------------------------------------
    75. ; Установить значение var = true, если выполняется хотя бы одно из условий cX; иначе установить var = false
    76. setifor macro var:req, c1:req, c2:req, c3, c4, c5, c6, c7, c8
    77. ; Установить значение var = true, если выполняются все условия cX; иначе установить var = false
    78. setifand macro var:req, c1:req, c2:req, c3, c4, c5, c6, c7, c8
    79. ; Установить значение var1 = true, а var2 = false, если выполняется условие cond (которые подставляются слитно с if); иначе установить var1 = false, а var2 = true
    80. setifelx macro cond:req, var1, var2
    81. ; Установить значение var = true, если выполняется хотя бы одно из условий cX (которые подставляются слитно с if); иначе установить var = false
    82. setiforx macro var:req, c1:req, c2:req, c3, c4, c5, c6, c7, c8
    83. ; Установить значение var = true, если выполняются все условия cX (которые подставляются слитно с if); иначе установить var = false
    84. setifandx macro var:req, c1:req, c2:req, c3, c4, c5, c6, c7, c8
    85. ;-------------------------------------------------------------------------------
    86. ; Если идентификатор value определён, установить значение const = value, иначе установить значение _const = defval
    87. defdef macro const:req, value:req, defval:req
    88. ; Если константа const определена, установить значение _const = const, иначе установить значение _const = defval
    89. _defdef macro const:req, defval:req
    90. ;-------------------------------------------------------------------------------
    91. ; Вывод сообщения txt об ошибке (одинаковый синтаксис для MASM и TASM)
    92. ?err macro txt
    93. ; Вывод сообщения txt об ошибке при выполнении условия cond
    94. ?errif macro cond:req, txt
    95. ; Аналогично ?errif, но условие подставляется слитно с if, например: ?errifx <ndef ok>, <Error message>
    96. ?errifx macro cond:req, txt
    97. ;-------------------------------------------------------------------------------
    98. ; Следующие идентификаторы определены для более удобного использования вложенных условных директив компиляции, например:
    99. ; if abc
    100. ;  ?if def
    101. ;    ??if ghi
    102. ;     ...
    103. ;    ??endif
    104. ;  ?endif
    105. ; endif
    106. ?if equ <if>
    107. ?ifdef equ <ifdef>
    108. ?ifndef equ <ifndef>
    109. ?ifb equ <ifb>
    110. ?ifnb equ <ifnb>
    111. ?ifidn equ <ifidn>
    112. ?ifidni equ <ifidni>
    113. ?ifdif equ <ifdif>
    114. ?ifdifi equ <ifdifi>
    115. ?if1 equ <if1>
    116. ?if2 equ <if2>
    117. ?else equ <else>
    118. ?elseif equ <elseif>
    119. ?elseifdef equ <elseifdef>
    120. ?elseifndef equ <elseifndef>
    121. ?elseifb equ <elseifb>
    122. ?elseifnb equ <elseifnb>
    123. ?elseifidn equ <elseifidn>
    124. ?elseifidni equ <elseifidni>
    125. ?elseifdif equ <elseifdif>
    126. ?elseifdifi equ <elseifdifi>
    127. ?elseif1 equ <elseif1>
    128. ?elseif2 equ <elseif2>
    129. ?endif equ <endif>
    130. ??if equ <if>
    131. ??ifdef equ <ifdef>
    132. ??ifndef equ <ifndef>
    133. ??ifb equ <ifb>
    134. ??ifnb equ <ifnb>
    135. ??ifidn equ <ifidn>
    136. ??ifidni equ <ifidni>
    137. ??ifdif equ <ifdif>
    138. ??ifdifi equ <ifdifi>
    139. ??if1 equ <if1>
    140. ??if2 equ <if2>
    141. ??else equ <else>
    142. ??elseif equ <elseif>
    143. ??elseifdef equ <elseifdef>
    144. ??elseifndef equ <elseifndef>
    145. ??elseifb equ <elseifb>
    146. ??elseifnb equ <elseifnb>
    147. ??elseifidn equ <elseifidn>
    148. ??elseifidni equ <elseifidni>
    149. ??elseifdif equ <elseifdif>
    150. ??elseifdifi equ <elseifdifi>
    151. ??elseif1 equ <elseif1>
    152. ??elseif2 equ <elseif2>
    153. ??endif equ <endif>
    Продолжение следует (весь код не помещается в одно сообщение)...
    Полный код см. в аттаче ;)
     

    Вложения:

    • xmacro_1.00.zip
      Размер файла:
      8,6 КБ
      Просмотров:
      667
  2. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Продолжение...
    Код (ASM):
    1. ;===============================================================================
    2. ;-------------------------------------------------------------------------------
    3. ;-- ОПРЕДЕЛЕНИЕ ЗНАЧЕНИЙ КОНСТАНТ ----------------------------------------------
    4. ;-------------------------------------------------------------------------------
    5. false = 0
    6. true = not false
    7. ; Установка isTASM = true и isMASM = false, если текущий компилятор - TASM, иначе наоборот
    8. setifelx <def ??Version>, isTASM, isMASM
    9. ; Установка идентификатора @32Bit (32-битный режим) в MASM
    10. ifdo isMASM, <@32Bit = (@WordSize eq 4)>
    11. ; Разрешены ли инструкции/регистры процессоров (в TASM @Cpu = 0 в режиме .586)
    12. @186 = (@Cpu and 2) or (@Cpu eq 0)
    13. @286 = (@Cpu and 3) or (@Cpu eq 0)
    14. @386 = (@Cpu and 8) or (@Cpu eq 0)
    15. @486 = (@Cpu and 10h) or (@Cpu eq 0)
    16. @586 = (@Cpu and 20h) or (@Cpu eq 0)
    17. @686 = @Cpu and 40h
    18. ; Включить режим оптимизации и использования локальных меток, начинающихся на @@
    19. ifdo isTASM, <_ smart, locals>
    20. ; Проверка требуемой версии данного include-файла, заданной через константу xmacro_ver_req или xmac_ver_req
    21. ifx <def xmacro_ver_req>, <?errif <xmacro_ver_req gt xmacro_ver>, <Version of 'xmacro.inc' is less than required :(>>
    22. ifx <def xmac_ver_req>, <?errif <xmac_ver_req gt xmacro_ver>, <Version of 'xmacro.inc' is less than required :(>>
    23. ;===============================================================================
    24. ;-------------------------------------------------------------------------------
    25. ;-- МАКРОСЫ, ОПИСЫВАЮЩИЕ ИЛИ УПРОЩАЮЩИЕ ИСПОЛЬЗОВАНИЕ ИНСТРУКЦИЙ ПРОЦЕССОРА ----
    26. ;-------------------------------------------------------------------------------
    27. ; Недокументированная инструкция salc (setalc)
    28. salc macro
    29. setalc equ <salc>
    30. ; Инструкция rdtsc
    31. if isTASM
    32.   rdtsc macro
    33. endif
    34. ;-------------------------------------------------------------------------------
    35. ; Прыжок через 1 байт; если указан 1-байтовый регистр reg, его значение изменяется, но сохраняются флаги, иначе изменяются флаги, но сохраняются регистры
    36. jmp_1 macro reg
    37. ; Прыжок через 2 байта; если указан 2-байтовый регистр reg, его значение изменяется, но сохраняются флаги, иначе изменяются флаги, но сохраняются регистры
    38. jmp_2 macro reg
    39. ; Прыжок через 4 байта; если указан 4-байтовый регистр reg, его значение изменяется, но сохраняются флаги, иначе изменяются флаги, но сохраняются регистры
    40. jmp_4 macro reg
    41. jmps equ <jmp short>
    42. jmpn equ <jmp near>
    43. ; jmp far seg:ofs (если seg:ofs не указан, генерируется только 1 байт опкода)
    44. jmpf macro seg, ofs
    45. ; call far seg:ofs (если seg:ofs не указан, генерируется только 1 байт опкода)
    46. callf macro seg, ofs
    47. ; call int (pushf + callf)
    48. calli macro seg, ofs
    49. ; Определяет nop'ы в количестве cnt штук
    50. nops macro cnt:req
    51. ;-------------------------------------------------------------------------------
    52. ; Выполнение присвоения значения регистру с помощью mov или xor (если src = 0)
    53. ; Чтобы передать в параметре src константу, необходимо поставить перед ней % (movx ax,%val), иначе xor не выполнится
    54. movx macro dst:req, src:req
    55. ; Выполнение сравнение регистра с помощью cmp или test (если src = 0)
    56. ; Чтобы передать в параметре src константу, необходимо поставить перед ней % (cmpx ax,%val), иначе test не выполнится
    57. cmpx macro dst:req, src:req
    58. ; Выполнение присвоения op = val через стек
    59. movp macro op:req, val:req
    60. ; Выполнение присвоения op = val через временный регистр temp (по умолчанию ax; например, movt ds,@data или movt es,0A000h,dx)
    61. movt macro op:req, val:req, temp:=<ax>
    62. ; Обмен значениями op1 и op2 через стек
    63. ; Макрос не проверяет соответствие разрядности операндов !!!
    64. xchgp macro op1:req, op2:req
    65. ; Сохранение регистров в одну строку: push ax bx cx dx
    66. pushx macro regs:vararg
    67. ; Восстановление регистров в одну строку: pop dx cx bx ax
    68. popx macro regs:vararg
    69. ; Восстановление регистров в обратном порядке: popb ax bx cx dx
    70. popb macro regs:vararg
    71. ; Запись ip (адрес следующей строки) в op, используя стек
    72. ; Макрос не проверяет соответствие разрядности кода и операнда !!!
    73. getip macro op:req
    74. ; Запись флагов в op, используя стек
    75. ; Макрос не проверяет соответствие разрядности флагов и операнда !!!
    76. getf macro op:req
    77. ; Запись слова флагов в op, используя стек
    78. ; Макрос не проверяет соответствие разрядности флагов и операнда !!!
    79. getfw macro op:req
    80. ; Запись двойного слова флагов в op, используя стек
    81. ; Макрос не проверяет соответствие разрядности флагов и операнда !!!
    82. getfd macro op:req
    83. ; Запись op в регистр флагов, используя стек
    84. ; Макрос не проверяет соответствие разрядности флагов и операнда !!!
    85. setf macro op:req
    86. ; Запись слова op в регистр флагов, используя стек
    87. ; Макрос не проверяет соответствие разрядности флагов и операнда !!!
    88. setfw macro op:req
    89. ; Запись двойного слова op в регистр флагов, используя стек
    90. ; Макрос не проверяет соответствие разрядности флагов и операнда !!!
    91. setfd macro op:req
    92. ; Установка флага ZF=ZR=1 (влияет и на другие флаги: CF=0, PF=1, AF=0, SF=0, OF=0)
    93. stz macro
    94. ; Получить абсолютное (положительное) значение op (минимальное отрицательное значение остаётся неизменным, при этом SF=1, OF=1, иначе SF=0, SF=0)
    95. absx macro op:req
    96. ; Получить абсолютное (положительное) значение регистра al (значение -128 остаётся неизменным, при этом SF=1, OF=1, иначе SF=0, SF=0)
    97. ; Работает быстрее, чем absx; при этом: ah = 0 и CF=0, если исходное значение al положительное, иначе ah = -1, CF=1
    98. absal macro
    99. ; Получить абсолютное (положительное) значение регистра ax (значение -32768 остаётся неизменным, при этом SF=1, OF=1, иначе SF=0, SF=0)
    100. ; Работает быстрее, чем absx; при этом: dx = 0 и CF=0, если исходное значение ax положительное, иначе dx = -1, CF=1
    101. absax macro
    102. ; Получить абсолютное (положительное) значение регистра ax (значение -2147483648 остаётся неизменным, при этом SF=1, OF=1, иначе SF=0, SF=0)
    103. ; Работает быстрее, чем absx; при этом: edx = 0 и CF=0, если исходное значение eax положительное, иначе edx = -1, CF=1
    104. abseax macro
    105. ;-------------------------------------------------------------------------------
    106. ; lodsb/lodsw/lodsd с использованием сегментов, отличных от ds:
    107. ; lodsb_seg, lodsw_seg, lodsd_seg с названием сегментного регистра в качестве аргумента (например, lodsb_seg es)
    108. ; lodsb_es, lodsb_cs, lodsb_ss, lodsb_fs, lodsb_gs,
    109. ; lodsw_es, lodsw_cs, lodsw_ss, lodsw_fs, lodsw_gs,
    110. ; lodsd_es, lodsd_cs, lodsd_ss, lodsd_fs, lodsd_gs без аргументов
    111. ; outsb/outsw/outsd с использованием сегментов, отличных от ds:
    112. ; outsb_seg, outsw_seg, outsd_seg с названием сегментного регистра в качестве аргумента (например, outsb_seg es)
    113. ; outsb_es, outsb_cs, outsb_ss, outsb_fs, outsb_gs,
    114. ; outsw_es, outsw_cs, outsw_ss, outsw_fs, outsw_gs,
    115. ; outsd_es, outsd_cs, outsd_ss, outsd_fs, outsd_gs без аргументов
    116. ;-------------------------------------------------------------------------------
    117. ; Вызов прерывания no с установкой регистров reg1 = val1, reg2 = val2...
    118. ; Если указан только reg1 без val1, то значение reg1 заносится в ah (или ax, если число > 0FFh)
    119. ; Например: intfn 16h,0 или intfn 15h,ah,86h,cx,0,dx,10000
    120. intfn macro no:req, reg1:req, val1, reg2, val2, reg3, val3, reg4, val4, reg5, val5
    Также имеется краткий вариант, в котором отсутствует примерно половина этих макросов (специфических).

    p.s. Что-то вся вёрстка поехала (включая пустые строки). Какой-то глюк на форуме, видимо... :search:
     
  3. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Обновление: версия 1.01.

    xmacro.inc:
    Код (Text):
    1. -= ИСТОРИЯ ВЕРСИЙ =-
    2.  
    3. v1.01 (26.01.2017)
    4. [+] Добавлены идентификаторы $ax, $bx, $cx, $dx, $si, $di, $bp, $sp, $word, j$cxz, cwdq$, pushf$, popf$.
    5. [+] Добавлен псевдоним ifndo.
    6. [*] В макросы defdef и _defdef добавлен дополнительный параметр, позволяющий делать проверку ещё одной константы.
    7. [*] В макросы ?err, ?errif, ?errifx добавлен дополнительный параметр, позволяющий добавлять к сообщению 3 восклицательных знака.
    8. [*] Исправлен баг в макросе movt.
    9.  
    10. v1.00 (09.01.2017)
    11. [!] Самая первая версия.
    xmac.inc:
    Код (Text):
    1. -= ИСТОРИЯ ВЕРСИЙ =-
    2.  
    3. v1.01 (26.01.2017)
    4. [+] Добавлены идентификаторы $ax, $bx, $cx, $dx, $si, $di, $bp, $sp, $word, j$cxz, cwdq$, pushf$, popf$.
    5. [+] Добавлены макросы iforel, ifandel, iforelx, ifandelx (из полной редакции).
    6. [+] Добавлен псевдоним ifndo.
    7. [*] В макросы defdef и _defdef добавлен дополнительный параметр, позволяющий делать проверку ещё одной константы.
    8. [*] В макросы ?err, ?errif, ?errifx добавлен дополнительный параметр, позволяющий добавлять к сообщению 3 восклицательных знака.
    9. [-] Из данной редакции удалены макросы movt, movp, xchgp, calli, outsXXX, intfn.
    10. [-] Из данной редакции удалена проверка xmacro_ver_req (поскольку это могло явиться причиной сообщения об ошибке при включении обеих редакций).
    11.  
    12. v1.00 (09.01.2017)
    13. [!] Самая первая версия.
     

    Вложения:

    • xmacro_1.01.zip
      Размер файла:
      9,6 КБ
      Просмотров:
      476
  4. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Обновление: версия 1.02.

    Код (Text):
    1. -= ИСТОРИЯ ВЕРСИЙ =-
    2.  
    3. v1.02 (01.02.2017)
    4. [+] Добавлен макрос loopx, генерирующий dec + jnz (jns).
    5. [*] (В ПОЛНОЙ РЕДАКЦИИ) В макросе movt значение параметра temp по умолчанию изменено с ax на $ax.
    6. [*] В макросе ?err для добавления ' !!!' в конец сообщения параметр exclam должен быть <> 0 (до этого достаточно было задать любое значение, в т.ч. 0).
     

    Вложения:

    • xmacro_1.02.zip
      Размер файла:
      10 КБ
      Просмотров:
      486
  5. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    И снова обновление: версия 1.03.
    Код (Text):
    1. -= ИСТОРИЯ ВЕРСИЙ =-
    2. v1.03 (08.03.2017)
    3. [+] Добавлены макросы doif, doifn и doifx, работающие аналогично ifdo, ifndo и ifx, но позволяющие указывать параметр do без <угловых скобок> (ifdo, ifndo и ifx сохранены для обратной совместимости).
    4. [+] Добавлены макросы doifset, doifnset, doifsete и ifsetel, проверяющие и определение идентификатора, и его значение.
    5. [+] Добавлены макросы aligndata, aligncode, alignd, alignc, alignds, aligncs.
    6. [+] Добавлен идентификатор dw$, определяющий dw или dd в зависимости от разрядности кода.
    7. [+] Добавлены идентификаторы proto = procdesc и invoke = call для TASM.
    8. [+] По умолчанию данный include-файл включает директивы locals и smart для TASM; если нужно их отключить, установите константу xnodir = 1 ДО включения файла.
    9. [+] Требуемую версию данного include-файла можно теперь проверять не только через константу xmacro_ver_req, но и через макрос check_xmacro_ver (после подключения файла), что исключает возможность опечатки.
    10. [*] Сделаны некоторые перестановки и изменения в макросах (например, ifel переписан без использования вложенных макросов, что должно увеличить скорость и упростить обнаружение ошибок в коде).
    (изменения приведены для полной версии xmacro.inc).
     

    Вложения:

    • xmacro_1.03.zip
      Размер файла:
      12,1 КБ
      Просмотров:
      488
  6. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.074
    Автор, а под линь(линукс) Асмить не пробовал?
     
  7. Jupiter

    Jupiter Jupiter

    Публикаций:
    0
    Регистрация:
    12 авг 2004
    Сообщения:
    530
    Адрес:
    Russia
    Jin X, посмотри пример с обработкой условно неограниченного (:VARARG) количества параметров (полезно для твоего макро "_"):

    Код (Text):
    1. xcall   Macro procedure,parameters:VARARG
    2.     Local param,reversed
    3.     reversed TEXTEQU <>
    4. %   For param,<parameters>
    5.         reversed CATSTR <param>,<!,>,reversed
    6.     EndM
    7. %   For param,<reversed>
    8.         push    param
    9.     EndM
    10.     call    procedure
    11. EndM
     
  8. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    UbIvItS, пробовал немного, а что? :)
    Jupiter, спасибо за пример. Я пробовал VARARG + IRP, но такой вариант не работал. Посмотрю такой вариант. Главное, чтобы он работал и с TASM тоже (а там FOR'а нет, только IRP)...
    p.s. А что % в данном примере даёт?

    Сейчас у меня другая проблема возникла, см. ниже (в "истории версий" под знаком [!])...
     
    Последнее редактирование: 10 мар 2017
  9. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Скорое обновление: версия 1.04.

    Код (Text):
    1. -= ИСТОРИЯ ВЕРСИЙ =-
    2. v1.04 (10.03.2017)
    3. [!] Обнаружен баг, который появился вместе с макросами doifXXX в предыдущей версии (1.03), и я пока не знаю как его исправить (если знаете, напишите мне) !!!
    4.     MASM выдаёт ошибку при совместном использовании макросов doifXXX и _ с параметрами, содержащими запятые в угловых скобках (например, doif x, _ <mov ax,bx>), параметр
    5.     макроса _ разделяется на несколько, будто угловых скобок нет (данный пример работает аналогично doif x, _ mov ax,bx; т.е. макрос _ получает 2 параметра: mov ax и bx).
    6.     Пока я вижу только два варианта решения данной проблемы:
    7.     1. использовать макросы ifXXX, заключая также и макрос _ в угловые скобки (ifdo x, <_ <mov ax,bx>>) - это ЛУЧШИЙ ВАРИАНТ,
    8.     2. использовать двойные угловые скобки (doif x, _ <<mov ax,bx>>), однако этот вариант НЕ работает в TASM, что плохо, учитывая, что данный include-файл является универсальным для TASM и MASM.
    9.     p.s. Эта проблема проявляется у макросов doifXXX не только с макросом _, но и с другими, принимающими несколько параметров, которые могут содержать запятые (например, doif x, ?errif <hello, world>).
    10. [+] Добавлены макросы ifnsetel и ifseteel (в дополнение к ifsetel) и псевдонимы для всех 3-х макросов: ifset, ifnset и ifsete.
    11. [+] Добавлен макрос fastnops и константа fastnopsprefix, а макрос aligncode получил дополнительный параметр prefix и использует (так же, как и alignc и aligncs) nop'ы с префиксами.
    12. [*] Исправлена ошибка в макросе ifsetel, возникающая при использовании угловых скобок в do1 и/или do0.
    13. [*] Макрос _ расширен до 16 параметров.
    14. [*] Макрос ifelif переписан без использования вложенных макросов, в других макросах doif-подобные макросы заменены на ifdo-подобные.
    (изменения приведены для полной редакции xmacro.inc, в сокращённой xmac.inc их чуть меньше).
     

    Вложения:

    • xmacro_1.04.zip
      Размер файла:
      14 КБ
      Просмотров:
      500
  10. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708
    перед директивой for указан знак процента (%). Обычно он означает, что текст интерпретируется как выражение
    Jin X,
    перечитай пожалуйста Макросы
    Пильщиков пишет о ТАСМе, Соколенко, Зубков и Edmond о МАСМе
     
  11. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Mikl___, я понимаю как % работает применительно к константам, но каким образом это работает с For ?
     
  12. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.074
    под линем как-то органичней что ль. хотя, конечно, дело привычки :) c другой стороны -- под линем больше возможностей для оптимизации кодов.
     
  13. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    GCC inline asm + сишный препроцессор рулят.
    Код (C++):
    1.  
    2.         #define OP2_ALIGN(OP) \
    3.             /* Align destination */ \
    4.             __ASM_EMIT("1:") \
    5.             __ASM_EMIT("test        $0x0f, %[dst]") \
    6.             __ASM_EMIT("jz          2f") \
    7.             __ASM_EMIT("movss       0x00(%[dst]), %%xmm0") \
    8.             __ASM_EMIT("movss       0x00(%[src]), %%xmm4") \
    9.             __ASM_EMIT(OP "ss       %%xmm4, %%xmm0") \
    10.             __ASM_EMIT("movss       %%xmm0, 0x00(%[dst])") \
    11.             __ASM_EMIT("add         $0x04, %[src]") \
    12.             __ASM_EMIT("add         $0x04, %[dst]") \
    13.             __ASM_EMIT("dec         %[count]") \
    14.             __ASM_EMIT("jnz         1b") \
    15.             __ASM_EMIT("jmp         20000f") \
    16.             __ASM_EMIT("2:")
    17.  
    18.         #define OP2_CORE(OP, MV_SRC)   \
    19.             __ASM_EMIT("sub         $0x10, %[count]") \
    20.             __ASM_EMIT("jb          2f") \
    21.             /* 16x blocks */ \
    22.             __ASM_EMIT("1:") \
    23.             __ASM_EMIT("movaps      0x00(%[dst]), %%xmm0") \
    24.             __ASM_EMIT("movaps      0x10(%[dst]), %%xmm1") \
    25.             __ASM_EMIT("movaps      0x20(%[dst]), %%xmm2") \
    26.             __ASM_EMIT("movaps      0x30(%[dst]), %%xmm3") \
    27.             __ASM_EMIT(MV_SRC "     0x00(%[src]), %%xmm4") \
    28.             __ASM_EMIT(MV_SRC "     0x10(%[src]), %%xmm5") \
    29.             __ASM_EMIT(MV_SRC "     0x20(%[src]), %%xmm6") \
    30.             __ASM_EMIT(MV_SRC "     0x30(%[src]), %%xmm7") \
    31.             __ASM_EMIT(OP "ps       %%xmm4, %%xmm0") \
    32.             __ASM_EMIT(OP "ps       %%xmm5, %%xmm1") \
    33.             __ASM_EMIT(OP "ps       %%xmm6, %%xmm2") \
    34.             __ASM_EMIT(OP "ps       %%xmm7, %%xmm3") \
    35.             __ASM_EMIT("movaps      %%xmm0, 0x00(%[dst])") \
    36.             __ASM_EMIT("movaps      %%xmm1, 0x10(%[dst])") \
    37.             __ASM_EMIT("movaps      %%xmm2, 0x20(%[dst])") \
    38.             __ASM_EMIT("movaps      %%xmm3, 0x30(%[dst])") \
    39.             __ASM_EMIT("add         $0x40, %[src]") \
    40.             __ASM_EMIT("add         $0x40, %[dst]") \
    41.             __ASM_EMIT("sub         $0x10, %[count]") \
    42.             __ASM_EMIT("jae         1b") \
    43.             /* 8x blocks */ \
    44.             __ASM_EMIT("2:") \
    45.             __ASM_EMIT("add         $0x10, %[count]") \
    46.             __ASM_EMIT("test        $8, %[count]") \
    47.             __ASM_EMIT("jz          3f") \
    48.             __ASM_EMIT("movaps      0x00(%[dst]), %%xmm0") \
    49.             __ASM_EMIT("movaps      0x10(%[dst]), %%xmm1") \
    50.             __ASM_EMIT(MV_SRC "     0x00(%[src]), %%xmm4") \
    51.             __ASM_EMIT(MV_SRC "     0x10(%[src]), %%xmm5") \
    52.             __ASM_EMIT(OP "ps       %%xmm4, %%xmm0") \
    53.             __ASM_EMIT(OP "ps       %%xmm5, %%xmm1") \
    54.             __ASM_EMIT("movaps      %%xmm0, 0x00(%[dst])") \
    55.             __ASM_EMIT("movaps      %%xmm1, 0x10(%[dst])") \
    56.             __ASM_EMIT("add         $0x20, %[src]") \
    57.             __ASM_EMIT("add         $0x20, %[dst]") \
    58.             /* 4x blocks */ \
    59.             __ASM_EMIT("3:") \
    60.             __ASM_EMIT("test        $4, %[count]") \
    61.             __ASM_EMIT("jz          4f") \
    62.             __ASM_EMIT("movaps      0x00(%[dst]), %%xmm0") \
    63.             __ASM_EMIT(MV_SRC "     0x00(%[src]), %%xmm4") \
    64.             __ASM_EMIT(OP "ps       %%xmm4, %%xmm0") \
    65.             __ASM_EMIT("movaps      %%xmm0, 0x00(%[dst])") \
    66.             __ASM_EMIT("add         $0x10, %[src]") \
    67.             __ASM_EMIT("add         $0x10, %[dst]") \
    68.             /* 1x blocks */ \
    69.             __ASM_EMIT("4:") \
    70.             __ASM_EMIT("and         $3, %[count]") \
    71.             __ASM_EMIT("jz          20000f") \
    72.             __ASM_EMIT("5:") \
    73.             __ASM_EMIT("movss       0x00(%[dst]), %%xmm0") \
    74.             __ASM_EMIT("movss       0x00(%[src]), %%xmm4") \
    75.             __ASM_EMIT(OP "ss       %%xmm4, %%xmm0") \
    76.             __ASM_EMIT("movss       %%xmm0, 0x00(%[dst])") \
    77.             __ASM_EMIT("add         $0x04, %[src]") \
    78.             __ASM_EMIT("add         $0x04, %[dst]") \
    79.             __ASM_EMIT("dec         %[count]") \
    80.             __ASM_EMIT("jnz         5b")
    81.  
    82.  
    83.         void add2(float *dst, const float *src, size_t count)
    84.         {
    85.             __asm__ __volatile__
    86.             (
    87.                 __ASM_EMIT("test        %[count], %[count]")
    88.                 __ASM_EMIT("jz          20000f")
    89.  
    90.                 OP2_ALIGN("add")
    91.  
    92.                 __ASM_EMIT("test        $0x0f, %[src]")
    93.                 __ASM_EMIT("jnz         10001f")
    94.                     OP2_CORE("add", "movaps")
    95.                     __ASM_EMIT("jmp         20000f")
    96.                 __ASM_EMIT("10001:")
    97.                     OP2_CORE("add", "movups")
    98.  
    99.                 __ASM_EMIT("20000:")
    100.  
    101.                 : [dst] "+r" (dst), [src] "+r" (src), [count] "+r" (count)
    102.                 :
    103.                 : "%xmm0", "%xmm1", "%xmm2", "%xmm3",
    104.                   "%xmm4", "%xmm5", "%xmm6", "%xmm7"
    105.             );
    106.         }
    107.  
    108.         void sub2(float *dst, const float *src, size_t count)
    109.         {
    110.             __asm__ __volatile__
    111.             (
    112.                 __ASM_EMIT("test        %[count], %[count]")
    113.                 __ASM_EMIT("jz          20000f")
    114.  
    115.                 OP2_ALIGN("sub")
    116.  
    117.                 __ASM_EMIT("test        $0x0f, %[src]")
    118.                 __ASM_EMIT("jnz         10001f")
    119.                     OP2_CORE("sub", "movaps")
    120.                     __ASM_EMIT("jmp         20000f")
    121.                 __ASM_EMIT("10001:")
    122.                     OP2_CORE("sub", "movups")
    123.  
    124.                 __ASM_EMIT("20000:")
    125.  
    126.                 : [dst] "+r" (dst), [src] "+r" (src), [count] "+r" (count)
    127.                 :
    128.                 : "%xmm0", "%xmm1", "%xmm2", "%xmm3",
    129.                   "%xmm4", "%xmm5", "%xmm6", "%xmm7"
    130.             );
    131.         }
    132.  
    133.         void mul2(float *dst, const float *src, size_t count)
    134.         {
    135.             __asm__ __volatile__
    136.             (
    137.                 __ASM_EMIT("test        %[count], %[count]")
    138.                 __ASM_EMIT("jz          20000f")
    139.  
    140.                 OP2_ALIGN("mul")
    141.  
    142.                 __ASM_EMIT("test        $0x0f, %[src]")
    143.                 __ASM_EMIT("jnz         10001f")
    144.                     OP2_CORE("mul", "movaps")
    145.                     __ASM_EMIT("jmp         20000f")
    146.                 __ASM_EMIT("10001:")
    147.                     OP2_CORE("mul", "movups")
    148.  
    149.                 __ASM_EMIT("20000:")
    150.  
    151.                 : [dst] "+r" (dst), [src] "+r" (src), [count] "+r" (count)
    152.                 :
    153.                 : "%xmm0", "%xmm1", "%xmm2", "%xmm3",
    154.                   "%xmm4", "%xmm5", "%xmm6", "%xmm7"
    155.             );
    156.         }
    157.  
    158.         void div2(float *dst, const float *src, size_t count)
    159.         {
    160.             __asm__ __volatile__
    161.             (
    162.                 __ASM_EMIT("test        %[count], %[count]")
    163.                 __ASM_EMIT("jz          20000f")
    164.  
    165.                 OP2_ALIGN("div")
    166.  
    167.                 __ASM_EMIT("test        $0x0f, %[src]")
    168.                 __ASM_EMIT("jnz         10001f")
    169.                     OP2_CORE("div", "movaps")
    170.                     __ASM_EMIT("jmp         20000f")
    171.                 __ASM_EMIT("10001:")
    172.                     OP2_CORE("div", "movups")
    173.  
    174.                 __ASM_EMIT("20000:")
    175.  
    176.                 : [dst] "+r" (dst), [src] "+r" (src), [count] "+r" (count)
    177.                 :
    178.                 : "%xmm0", "%xmm1", "%xmm2", "%xmm3",
    179.                   "%xmm4", "%xmm5", "%xmm6", "%xmm7"
    180.             );
    181.         }
    182.  
    183.         #undef OP2_CORE
    184.         #undef OP2_ALIGN
    185.  
     
  14. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.615
    Адрес:
    Russia
    ????????????????????????????????????????????????????????????????????????????????
    У Пильщикова в книге масм, в той что у меня точно !!!
     
    yashechka нравится это.
  15. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708
    Rockphorr,
    ссылка на Макрсы, а там использовалась книга Пильщикова "Программирование на языке ассемблера IBM PC" – издательство "ДИАЛОГ-МИФИ", год издания 1994, 288 страниц. Приведены фрагменты из 11 главы "Макросредства". Книга написана на основе диалекта TASM.
     
  16. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Jupiter, Mikl___, я так и не понял что значит этот % применительно в For (а не к константе).
    Можете объяснить?
     
  17. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.615
    Адрес:
    Russia
    лучше всего скачать масм6.11 и запустить справку там все разжевано
    насколько помню это костыль влияющий на глубину разбора выражений при макрозаменах
     
  18. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    369
    Адрес:
    Кольца Сатурна
    Короче, понял я, как здесь % работает. Он интерпретирует в строке <reversed> слово reversed как значение локальной переменной, а не как строку (без % это будет просто строка <reversed>). А вот для <parameters> этого делать необязательно, т.к. переменные циклов подставляются всегда даже без %.
    Работает и в tasm, и в masm, что интересно!

    Скоро пришлю новую версию xmacro, кстати!
    Очень много новых макросов и изменений там будет! ;)
     
    Mikl___ нравится это.
  19. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    561
    Код (ASM):
    1.  
    2. ; поместить в память или регистр float-значение из памяти или регистра или непосредственного значения
    3. float_set MACRO flt_this:req, param:req
    4. LOCAL first, break
    5.    echo param
    6.    IFIDN <param>, <0.0>
    7.      and     flt_this, 0
    8.      echo is_zero
    9.    ELSEIFIDN <param>, <0.>
    10.      and     flt_this, 0
    11.      echo is_zero
    12.    ELSE
    13.      break = 0
    14.      ; если param регистр
    15.      FOR arg,<eax,ebx,ecx,edx,esp,ebp,esi,edi>
    16.        IFIDNI <arg>,<param>
    17.          mov     flt_this, param
    18.          break = 1
    19.          echo is_register
    20.          EXITM
    21.        ENDIF
    22.      ENDM
    23.      IF break EQ 0
    24.        ; если param непосредственое float значения
    25.        first SUBSTR <param>,1,1
    26.        echo first
    27.        FOR arg,<0,1,2,3,4,5,6,7,8,9,->
    28.          IFIDN <arg>,<first>   ;;@SUBSTR(<param>,1,1)
    29.            movflt   flt_this, param
    30.            break = 1
    31.            echo is_float_const
    32.            EXITM
    33.          ENDIF
    34.        ENDM
    35.      ENDIF
    36.      IF break EQ 0
    37.        mov     eax, param
    38.        mov     flt_this, eax
    39.        echo is_memory
    40.      ENDIF
    41.    ENDIF
    42. ENDM
    43.  
    Вот макрос, спотыкается на first SUBSTR <param>,1,1
    В first передаётся какая-то ерунда и далее макрос не правильно работает. Не пойму что за проблема.
    Этот макрос вложен в других макросы.
    Код (ASM):
    1. Fvector4_set MACRO vec_this:req, vec_x:req, vec_y:req, vec_z:req, vec_w:req
    2.    float_set   vec_this.x, vec_x
    3.    float_set   vec_this.y, vec_y
    4.    float_set   vec_this.z, vec_z
    5.    float_set   vec_this.w, vec_w
    6. ENDM
     
  20. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    561
    Не ошибка в IFIDN <arg>,<first>, если строки arg и first равны, то эта команда всё равно даёт ложь, то есть не срабатывает.
    Код (ASM):
    1. ; поместить непосредственое float значение в память или регистр.
    2. movflt MACRO param:req, const:req
    3.    mov     dword ptr param, 0
    4.    org     $-4
    5.    dd     const
    6. ENDM
    З.Ы.
    А наконец-то разобрался, надо так IFIDN first,<arg>