На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Для обсуждения создания операционных систем (ОС) используйте раздел Обсуждаем новые идеи.

3. Настоятельно рекомендую обратить особое внимание на правила форума, которые нарушаются чаще всего:
  3.1. Перед созданием темы просмотрите FAQ раздела Assembler и Полезные ссылки.
  3.2. Заголовок темы должен кратко отражать её суть. Темы с заголовками типа "Срочно помогите!" или "В чём проблема?" будут отправляться в Корзину для мусора.
  3.3. Исходники программ обязательно выделяйте тегами [code]...[/code] (одиночные инструкции можно не выделять).

Не забывайте также про главные ПРАВИЛА ФОРУМА!
Участники форума, нарушающие правила, будут наказываться, а вносящие вклад в развитие форума - награждаться (DigiMoney и прочими радостями).

Приятного вам общения! ;)
Модераторы: Jin X, Qraizer
  
> Полезные макросы, MASM/TASM
    Не претендую на создание чего-то нового и гениального, но макросы довольно полезные. Часть из того, что я сделал, уже делали другие. Тем не менее, большинство макросов придумано и сделано мною с нуля, остальной код переписан по-своему :)

    Вот эти макросы (полный вариант, только заголовки):
    ExpandedWrap disabled
      ;############################################
      ;##                                        ##
      ;##   -= EXTRA MACROSES (FULL EDITION) =-  ##
      ;##      МАКРОСЫ ДЛЯ MASM/TASM (16/32)     ##
      ;##             Полный вариант             ##
      ;##         [ v1.00 :: 09.01.2017 ]        ##
      ;##                                        ##
      ;##  (c) 2017 by Jin X (jin.x@sources.ru)  ##
      ;##           http://xk7.ru/p/a/i          ##
      ;##                                        ##
      ;############################################
       
      xmacro_ver  =   100h            ; версия данного файла (word: старший байт - целая часть, младший - дробная)
       
      ;-------------------------------------------------------------------------------
       
      @       equ <offset>
      $b      equ <byte ptr>
      $w      equ <word ptr>
      $d      equ <dword ptr>
      $f      equ <fword ptr>
      $q      equ <qword ptr>
      $t      equ <tbyte ptr>
      $s      equ <short>
      $n      equ <near>
      $f      equ <far>
       
      ; Выполнение инструкций/директив/макросов, заданных одной строкой
      _       macro   p1, p2, p3, p4, p5, p6, p7, p8, p9, p10
       
      ;-------------------------------------------------------------------------------
      ;-- УСЛОВНЫЕ МАКРОСЫ -----------------------------------------------------------
      ;-------------------------------------------------------------------------------
       
      ; Если cond, исполнить do1; иначе do0
      ifel        macro   cond:req, do1, do0
      ifdo        equ <ifel>
       
      ifn     equ <ife>
       
      ; Если НЕ cond, исполнить do1; иначе do0
      ifnel       macro   cond:req, do1, do0
      ifeel       equ <ifnel>
       
      ; Если cond1, исполнить do1; иначе если cond2, исполнить do2; иначе do0
      ifelif      macro   cond1:req, do1, cond2:req, do2, do0
       
      ; ifdef id (если идентификатор определён), исполнить do1; иначе do0
      ifdefel     macro   id:req, do1, do0
       
      ; ifndef id (если идентификатор НЕ определён), исполнить do1; иначе do0
      ifndefel    macro   id:req, do1, do0
       
      ; ifb exp (если выражение пустое), исполнить do1; иначе do0
      ifbel       macro   exp, do1, do0
       
      ; Если выражение exp пустое или состоит из пробелов, исполнить do1; иначе do0
      ifbbel      macro   exp, do1, do0
       
      ; ifnb exp (если выражение НЕпустое), исполнить do1; иначе do0
      ifnbel      macro   exp, do1, do0
       
      ; Если выражение exp НЕпустое и НЕ состоит из пробелов, исполнить do1; иначе do0
      ifnbbel     macro   exp, do1, do0
       
      ; ifidn exp1, exp2 (если значения совпадают С учётом регистра символов), исполнить do1; иначе do0
      ifidnel     macro   exp1:req, exp2:req, do1, do0
       
      ; ifidni cond (если значения совпадают БЕЗ учёта регистра символов), исполнить do1; иначе do0
      ifidniel    macro   exp1:req, exp2:req, do1, do0
       
      ; ifidn exp1, exp2 (если значения различаются С учётом регистра символов), исполнить do1; иначе do0
      ifdifel     macro   exp1:req, exp2:req, do1, do0
       
      ; ifidni cond (если значения различаются БЕЗ учёта регистра символов), исполнить do1; иначе do0
      ifdifiel    macro   exp1:req, exp2:req, do1, do0
       
      ; Если cond1 или cond2 (условие cond2 проверяется только в том случае, если cond1 не выполнилось), исполнить do1; иначе do0
      iforel      macro   cond1:req, cond2:req, do1, do0
       
      ; Если cond1 и cond2 (условие cond2 проверяется только в том случае, если cond1 выполнилось), исполнить do1; иначе do0
      ifandel     macro   cond1:req, cond2:req, do1, do0
       
      ; Аналогично ifel, но условие подставляется слитно с if, например: ifelx <def debug>, <int 3>, nop
      ifelx       macro   cond:req, do1, do0
      ifx     equ <ifelx>
       
      ; Аналогично ifnel, но условие подставляется слитно с if, например: ifnelx <def debug>, nop, <int 3>
      ifnelx      macro   cond:req, do1, do0
      ifeelx      equ <ifnelx>
       
      ; Аналогично ifelif, но условия подставляются слитно с if, например: ifelifx <def debug>, <int 3>, <idn <spec>, <stosb>>, stosb, nop
      ifelifx     macro   cond1:req, do1, cond2:req, do2, do0
       
      ; Аналогично iforel, но условия подставляются слитно с if
      iforelx     macro   cond1:req, cond2:req, do1, do0
       
      ; Аналогично ifandel, но условия подставляются слитно с if
      ifandelx    macro   cond1:req, cond2:req, do1, do0
       
      ;-------------------------------------------------------------------------------
       
      ; Установить значение var = true, если выполняется хотя бы одно из условий cX; иначе установить var = false
      setifor     macro   var:req, c1:req, c2:req, c3, c4, c5, c6, c7, c8
       
      ; Установить значение var = true, если выполняются все условия cX; иначе установить var = false
      setifand    macro   var:req, c1:req, c2:req, c3, c4, c5, c6, c7, c8
       
      ; Установить значение var1 = true, а var2 = false, если выполняется условие cond (которые подставляются слитно с if); иначе установить var1 = false, а var2 = true
      setifelx    macro   cond:req, var1, var2
       
      ; Установить значение var = true, если выполняется хотя бы одно из условий cX (которые подставляются слитно с if); иначе установить var = false
      setiforx    macro   var:req, c1:req, c2:req, c3, c4, c5, c6, c7, c8
       
      ; Установить значение var = true, если выполняются все условия cX (которые подставляются слитно с if); иначе установить var = false
      setifandx   macro   var:req, c1:req, c2:req, c3, c4, c5, c6, c7, c8
       
      ;-------------------------------------------------------------------------------
       
      ; Если идентификатор value определён, установить значение const = value, иначе установить значение _const = defval
      defdef      macro   const:req, value:req, defval:req
       
      ; Если константа const определена, установить значение _const = const, иначе установить значение _const = defval
      _defdef     macro   const:req, defval:req
       
      ;-------------------------------------------------------------------------------
       
      ; Вывод сообщения txt об ошибке (одинаковый синтаксис для MASM и TASM)
      ?err        macro   txt
       
      ; Вывод сообщения txt об ошибке при выполнении условия cond
      ?errif      macro   cond:req, txt
       
      ; Аналогично ?errif, но условие подставляется слитно с if, например: ?errifx <ndef ok>, <Error message>
      ?errifx     macro   cond:req, txt
       
      ;-------------------------------------------------------------------------------
       
      ; Следующие идентификаторы определены для более удобного использования вложенных условных директив компиляции, например:
      ; if abc
      ;  ?if def
      ;    ??if ghi
      ;     ...
      ;    ??endif
      ;  ?endif
      ; endif
      ?if     equ <if>
      ?ifdef      equ <ifdef>
      ?ifndef     equ <ifndef>
      ?ifb        equ <ifb>
      ?ifnb       equ <ifnb>
      ?ifidn      equ <ifidn>
      ?ifidni     equ <ifidni>
      ?ifdif      equ <ifdif>
      ?ifdifi     equ <ifdifi>
      ?if1        equ <if1>
      ?if2        equ <if2>
      ?else       equ <else>
      ?elseif     equ <elseif>
      ?elseifdef  equ <elseifdef>
      ?elseifndef equ <elseifndef>
      ?elseifb    equ <elseifb>
      ?elseifnb   equ <elseifnb>
      ?elseifidn  equ <elseifidn>
      ?elseifidni equ <elseifidni>
      ?elseifdif  equ <elseifdif>
      ?elseifdifi equ <elseifdifi>
      ?elseif1    equ <elseif1>
      ?elseif2    equ <elseif2>
      ?endif      equ <endif>
       
      ??if        equ <if>
      ??ifdef     equ <ifdef>
      ??ifndef    equ <ifndef>
      ??ifb       equ <ifb>
      ??ifnb      equ <ifnb>
      ??ifidn     equ <ifidn>
      ??ifidni    equ <ifidni>
      ??ifdif     equ <ifdif>
      ??ifdifi    equ <ifdifi>
      ??if1       equ <if1>
      ??if2       equ <if2>
      ??else      equ <else>
      ??elseif    equ <elseif>
      ??elseifdef equ <elseifdef>
      ??elseifndef    equ <elseifndef>
      ??elseifb   equ <elseifb>
      ??elseifnb  equ <elseifnb>
      ??elseifidn equ <elseifidn>
      ??elseifidni    equ <elseifidni>
      ??elseifdif equ <elseifdif>
      ??elseifdifi    equ <elseifdifi>
      ??elseif1   equ <elseif1>
      ??elseif2   equ <elseif2>
      ??endif     equ <endif>
       
      ;===============================================================================
       
      ;-------------------------------------------------------------------------------
      ;-- ОПРЕДЕЛЕНИЕ ЗНАЧЕНИЙ КОНСТАНТ ----------------------------------------------
      ;-------------------------------------------------------------------------------
       
      false       =   0
      true        =   not false
       
      ; Установка isTASM = true и isMASM = false, если текущий компилятор - TASM, иначе наоборот
      setifelx    <def ??Version>, isTASM, isMASM
       
      ; Установка идентификатора @32Bit (32-битный режим) в MASM
      ifdo        isMASM, <@32Bit = (@WordSize eq 4)>
       
      ; Разрешены ли инструкции/регистры процессоров (в TASM @Cpu = 0 в режиме .586)
      @186        =   (@Cpu and 2) or (@Cpu eq 0)
      @286        =   (@Cpu and 3) or (@Cpu eq 0)
      @386        =   (@Cpu and 8) or (@Cpu eq 0)
      @486        =   (@Cpu and 10h) or (@Cpu eq 0)
      @586        =   (@Cpu and 20h) or (@Cpu eq 0)
      @686        =   @Cpu and 40h
       
      ; Включить режим оптимизации и использования локальных меток, начинающихся на @@
      ifdo        isTASM, <_ smart, locals>
       
      ; Проверка требуемой версии данного include-файла, заданной через константу xmacro_ver_req или xmac_ver_req
      ifx     <def xmacro_ver_req>, <?errif <xmacro_ver_req gt xmacro_ver>, <Version of 'xmacro.inc' is less than required :(>>
      ifx     <def xmac_ver_req>, <?errif <xmac_ver_req gt xmacro_ver>, <Version of 'xmacro.inc' is less than required :(>>
       
      ;===============================================================================
       
      ;-------------------------------------------------------------------------------
      ;-- МАКРОСЫ, ОПИСЫВАЮЩИЕ ИЛИ УПРОЩАЮЩИЕ ИСПОЛЬЗОВАНИЕ ИНСТРУКЦИЙ ПРОЦЕССОРА ----
      ;-------------------------------------------------------------------------------
       
      ; Недокументированная инструкция salc (setalc)
      salc        macro
      setalc      equ <salc>
       
      ; Инструкция rdtsc
      if      isTASM
        rdtsc     macro
      endif
       
      ;-------------------------------------------------------------------------------
       
      ; Прыжок через 1 байт; если указан 1-байтовый регистр reg, его значение изменяется, но сохраняются флаги, иначе изменяются флаги, но сохраняются регистры
      jmp_1       macro   reg
       
      ; Прыжок через 2 байта; если указан 2-байтовый регистр reg, его значение изменяется, но сохраняются флаги, иначе изменяются флаги, но сохраняются регистры
      jmp_2       macro   reg
       
      ; Прыжок через 4 байта; если указан 4-байтовый регистр reg, его значение изменяется, но сохраняются флаги, иначе изменяются флаги, но сохраняются регистры
      jmp_4       macro   reg
       
      jmps        equ <jmp short>
      jmpn        equ <jmp near>
       
      ; jmp far seg:ofs (если seg:ofs не указан, генерируется только 1 байт опкода)
      jmpf        macro   seg, ofs
       
      ; call far seg:ofs (если seg:ofs не указан, генерируется только 1 байт опкода)
      callf       macro   seg, ofs
       
      ; call int (pushf + callf)
      calli       macro   seg, ofs
       
      ; Определяет nop'ы в количестве cnt штук
      nops        macro   cnt:req
       
      ;-------------------------------------------------------------------------------
       
      ; Выполнение присвоения значения регистру с помощью mov или xor (если src = 0)
      ; Чтобы передать в параметре src константу, необходимо поставить перед ней % (movx ax,%val), иначе xor не выполнится
      movx        macro   dst:req, src:req
       
      ; Выполнение сравнение регистра с помощью cmp или test (если src = 0)
      ; Чтобы передать в параметре src константу, необходимо поставить перед ней % (cmpx ax,%val), иначе test не выполнится
      cmpx        macro   dst:req, src:req
       
      ; Выполнение присвоения op = val через стек
      movp        macro   op:req, val:req
       
      ; Выполнение присвоения op = val через временный регистр temp (по умолчанию ax; например, movt ds,@data или movt es,0A000h,dx)
      movt        macro   op:req, val:req, temp:=<ax>
       
      ; Обмен значениями op1 и op2 через стек
      ; Макрос не проверяет соответствие разрядности операндов !!!
      xchgp       macro   op1:req, op2:req
       
      ; Сохранение регистров в одну строку: push ax bx cx dx
      pushx       macro   regs:vararg
       
      ; Восстановление регистров в одну строку: pop dx cx bx ax
      popx        macro   regs:vararg
       
      ; Восстановление регистров в обратном порядке: popb ax bx cx dx
      popb        macro   regs:vararg
       
      ; Запись ip (адрес следующей строки) в op, используя стек
      ; Макрос не проверяет соответствие разрядности кода и операнда !!!
      getip       macro   op:req
       
      ; Запись флагов в op, используя стек
      ; Макрос не проверяет соответствие разрядности флагов и операнда !!!
      getf        macro   op:req
       
      ; Запись слова флагов в op, используя стек
      ; Макрос не проверяет соответствие разрядности флагов и операнда !!!
      getfw       macro   op:req
       
      ; Запись двойного слова флагов в op, используя стек
      ; Макрос не проверяет соответствие разрядности флагов и операнда !!!
      getfd       macro   op:req
       
      ; Запись op в регистр флагов, используя стек
      ; Макрос не проверяет соответствие разрядности флагов и операнда !!!
      setf        macro   op:req
       
      ; Запись слова op в регистр флагов, используя стек
      ; Макрос не проверяет соответствие разрядности флагов и операнда !!!
      setfw       macro   op:req
       
      ; Запись двойного слова op в регистр флагов, используя стек
      ; Макрос не проверяет соответствие разрядности флагов и операнда !!!
      setfd       macro   op:req
       
      ; Установка флага ZF=ZR=1 (влияет и на другие флаги: CF=0, PF=1, AF=0, SF=0, OF=0)
      stz     macro
       
      ; Получить абсолютное (положительное) значение op (минимальное отрицательное значение остаётся неизменным, при этом SF=1, OF=1, иначе SF=0, SF=0)
      absx        macro   op:req
       
      ; Получить абсолютное (положительное) значение регистра al (значение -128 остаётся неизменным, при этом SF=1, OF=1, иначе SF=0, SF=0)
      ; Работает быстрее, чем absx; при этом: ah = 0 и CF=0, если исходное значение al положительное, иначе ah = -1, CF=1
      absal       macro
       
      ; Получить абсолютное (положительное) значение регистра ax (значение -32768 остаётся неизменным, при этом SF=1, OF=1, иначе SF=0, SF=0)
      ; Работает быстрее, чем absx; при этом: dx = 0 и CF=0, если исходное значение ax положительное, иначе dx = -1, CF=1
      absax       macro
       
      ; Получить абсолютное (положительное) значение регистра ax (значение -2147483648 остаётся неизменным, при этом SF=1, OF=1, иначе SF=0, SF=0)
      ; Работает быстрее, чем absx; при этом: edx = 0 и CF=0, если исходное значение eax положительное, иначе edx = -1, CF=1
      abseax      macro
       
      ;-------------------------------------------------------------------------------
       
      ; lodsb/lodsw/lodsd с использованием сегментов, отличных от ds:
      ; lodsb_seg, lodsw_seg, lodsd_seg с названием сегментного регистра в качестве аргумента (например, lodsb_seg es)
      ; lodsb_es, lodsb_cs, lodsb_ss, lodsb_fs, lodsb_gs,
      ; lodsw_es, lodsw_cs, lodsw_ss, lodsw_fs, lodsw_gs,
      ; lodsd_es, lodsd_cs, lodsd_ss, lodsd_fs, lodsd_gs без аргументов
       
      ; outsb/outsw/outsd с использованием сегментов, отличных от ds:
      ; outsb_seg, outsw_seg, outsd_seg с названием сегментного регистра в качестве аргумента (например, outsb_seg es)
      ; outsb_es, outsb_cs, outsb_ss, outsb_fs, outsb_gs,
      ; outsw_es, outsw_cs, outsw_ss, outsw_fs, outsw_gs,
      ; outsd_es, outsd_cs, outsd_ss, outsd_fs, outsd_gs без аргументов
       
      ;-------------------------------------------------------------------------------
       
      ; Вызов прерывания no с установкой регистров reg1 = val1, reg2 = val2...
      ; Если указан только reg1 без val1, то значение reg1 заносится в ah (или ax, если число > 0FFh)
      ; Например: intfn 16h,0 или intfn 15h,ah,86h,cx,0,dx,10000
      intfn       macro   no:req, reg1:req, val1, reg2, val2, reg3, val3, reg4, val4, reg5, val5

    Также имеется краткий вариант, в котором отсутствует примерно половина этих макросов (специфических).

    Полный код см. в аттаче ;)

    asm7x
    Прикреплённый файлПрикреплённый файлxmacro_1.02.zip (10,01 Кбайт, скачиваний: 6)

    Старые версии:
    Прикреплённый файлПрикреплённый файлxmacro_1.01.zip (9,55 Кбайт, скачиваний: 8)
    Прикреплённый файлПрикреплённый файлxmacro_1.00.zip (8,56 Кбайт, скачиваний: 7)
    1 + 1 = 10
      user posted image Версия 1.01.

      xmacro.inc:
      ExpandedWrap disabled
        -= ИСТОРИЯ ВЕРСИЙ =-
         
        v1.01 (26.01.2017)
        [+] Добавлены идентификаторы $ax, $bx, $cx, $dx, $si, $di, $bp, $sp, $word, j$cxz, cwdq$, pushf$, popf$.
        [+] Добавлен псевдоним ifndo.
        [*] В макросы defdef и _defdef добавлен дополнительный параметр, позволяющий делать проверку ещё одной константы.
        [*] В макросы ?err, ?errif, ?errifx добавлен дополнительный параметр, позволяющий добавлять к сообщению 3 восклицательных знака.
        [*] Исправлен баг в макросе movt.
         
        v1.00 (09.01.2017)
        [!] Самая первая версия.

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

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


        [ Script Execution time: 0,1047 ]   [ 17 queries used ]   [ Generated: 28.02.17, 05:40 GMT ]