Всё разобрался что к чему. Код (ASM): ; поместить в память или регистр float-значение из памяти или регистра или непосредственого значения float_set MACRO flt_this:req, param:req LOCAL first, exit, exit_macro exit = 0 ; если param равен нулю FOR arg,<0.0,0.,0> IFIDN <arg>,<param> and flt_this, 0 exit = 1 EXITM ENDIF ENDM IF exit EQ 1 GOTO exit_macro ENDIF ; если param регистр FOR arg,<eax,ebx,ecx,edx,esp,ebp,esi,edi> IFIDNI <arg>,<param> mov flt_this, param exit = 1 EXITM ENDIF ENDM IF exit EQ 1 GOTO exit_macro ENDIF ; если param непосредственое float значения first SUBSTR <param>,1,1 FOR arg,<0,1,2,3,4,5,6,7,8,9,-> IFIDN first,<arg> movflt flt_this, param exit = 1 EXITM ENDIF ENDM IF exit EQ 1 GOTO exit_macro ENDIF ; param это память mov eax, param mov flt_this, eax :exit_macro ENDM Макрос оптимизирующий, типа как в C++.
Вот макрос более оптимальный. Код (ASM): ; найти в списке строк номер совпадающей строки, если не нашли - то возвращает ноль @SearchStr MACRO str1:req, params:VARARG LOCAL i, num i = 0 num = 0 FOR arg,<params> i = i + 1 IFIDNI <str1>,<arg> num = i EXITM ENDIF ENDM EXITM <num> ENDM ; поместить в память или регистр float-значение из памяти или регистра или непосредственого значения float_set MACRO flt_this:req, param:req ;; echo param ;; если param равен нулю IF @SearchStr(<param>,<0.0,0.,0>) and flt_this, 0 ;; echo is_zero EXITM ENDIF ;; если param регистр IF @SearchStr(<param>,<eax,ebx,ecx,edx,esp,ebp,esi,edi>) mov flt_this, param ;; echo is_register EXITM ENDIF ;; если param непосредственое float значения IF @SearchStr(%@SubStr(<param>,1,1), <0,1,2,3,4,5,6,7,8,9,->) movflt flt_this, param ;; echo is_float_const EXITM ENDIF ; param это память mov eax, param mov flt_this, eax ;; echo is_memory ENDM Одно не пойму, почему не работает конструкция ELSEIF @SearchStr(... То есть, макрофункция в блоке ELSEIF даёт ошибку препроцессора, использую ml от 10-й студии. Это баг? Или ещё что-то.
Вектор в МАСМе. Структура вектора обычно такая получается. Код (ASM): xr_vector struct ; (sizeof=16, align=4) _Alval dword ? ; 0 allocator object for values ; объект{цель} программы распределения для значений _Myfirst dword ? ; 4 pointer to beginning of array ; указатель на начало массива _Mylast dword ? ; 8 pointer to current end of sequence ; указатель на текущий конец последовательности _Myend dword ? ; 12 pointer to end of array ; указатель на конец массива xr_vector ends ; 16 Теперь надо сделать макросы для работы с этой структурой, макросы имитируют работу методов С++. Реализовать можно не все, нужны больше всего insert, erase, back, push_back, pop_back, size и другие. Вот тут проблема, как в структуре задать тип содержимого в векторе. Типа так: Код (ASM): children_invisible xr_vector <> ; 112 xr_vector<IRender_Visual *,xalloc<IRender_Visual *> > ? За комментированное это результат IDA Pro, то есть надо как то сохранить в структуре строку с названием класса т.е. структуры, что бы макрос знал размер структуры в контейнере. В хелпе МАСМ32 указано что есть какие-то дополнительные команды для работы со структурами. В общем, кто что предложит. Надо как то в структуре макроконстанту вложить с названием структуры. ЗЫ Как точно переводится "allocator object for values"?
Обнаружил что МАСМ таки поддерживает виртуальные функции(методы). Код (ASM): ;вызов виртуальной функции vcall MACRO _this:REQ, class_name_func:REQ, params:VARARG LOCAL num IFNB <params> num = @InStr(1, <&class_name_func>, <.>) .erre num, <"The symbol a point is not found."> invoke (@SubStr(<&class_name_func>, 1, num-1) ptr[eax+12345678h])@SubStr(<&class_name_func>, num), params org $-6 ENDIF IF @SearchStr(<_this>,<ebx,esp,ebp,esi,edi>) mov eax, dword ptr [_this] mov edx, dword ptr [eax+&class_name_func&] mov ecx, _this ELSE IFDIFI <_this>,<ecx> mov ecx, _this ENDIF mov eax, dword ptr [ecx] mov edx, dword ptr [eax+&class_name_func&] ENDIF call edx ENDM Но вот код создаёт не очень оптимальный. Здесь стиль аля VS C++, т.е. с оптимизацией. Использовать типа так. Код (ASM): mov ecx, [edi].pSurface vcall ecx, IDirect3DBaseTexture9.GetSurfaceLevel, ecx, 0, addr ppSurfaceLevel
Что значит "не работает"? Что за всеми любимая универсальная злосчастная фраза такая? Как не работает? В папке Samples\Win64 есть примеры, ищите внутри по слову printf.
Запихну пока сюда. Библиотечные макросы для MS-DOS, т.е. имитируется стандартный набор функций Си. Пока неполный набор. scanf решил не делать, из-за сложности реализации и бесконтрольности ввода, заменил на InputInt, потом добавлю InputFloat. Так же пример использования, программа вычисления даты пасхи. Проверил работоспособность на WinXP 32bit и MS-DOS 2.1 IBM PC 1982 (эмулятор 86BOX, VARCem). ЗЫ Ах да, ассемблер UASM ver. 2.46! ЗЫЫ Ключи компиляции uasm32 -mz easter.asm
Тут у меня немного макросов поднакопилось. Выкладываю. А то не сможете откомпилить мой хайкод. ЗЫ Сделал макрос createSpisok Т.к. ассемблер не поддерживает массивы. То сделал такой макрос. createSpisok(spisok, sdword, 4, 65, 2, -31, 0, 99, 2, 83, 782, 1) Создаёт структуру sSpisok Код (ASM): sSpisok struct ;(sizeof=8, align=4) pFirst dword ? ;//указатель на первый элемент массива pLast dword ? ;//указатель на последний элемент массива sSpisok ends Пример перебора коллекции. Код (ASM): .for (esi = spisok.pFirst: esi <= spisok.pLast: esi+=4) printf("%d ", dword ptr [esi]) .endfor Вот как то так заставляем ассемблер быть высокоуровневым!
У меня книга 1998 года, Москва.Диалог-МИФИ.1998 на странице 220 раздел 12.1 Работа в системе MASM. Так что это камень в огород TASM - покойный В.Н. Пильщиков перешел на MASM. Диалекты в ту пору еще не сильно различались видимо (ИМХО). Могу сфоткать.