Нужно в зависимости от значения var1 определить reg1 как имя регистра, но для equ выходит что последнее переопределяет все предыдущие вне зависимости от условий if var1 = 0 reg1 equ eax else if var1 = 1 reg1 equ ebx else if var1 = 2 reg1 equ ecx else if var1 = 3 reg1 equ edx else if var1 = 4 reg1 equ esi else if var1 = 5 reg1 equ edi else if var1 = 6 reg1 equ ebp end if в итоге всегда: reg1 = ebp
OpticalToxin, equ обрабатывает препроцессор, if и = – ассемблер. Если действительно хочется условий в препроцессоре: Код (Text): var equ 1 match =0,var { reg1 equ eax } match =1,var { reg1 equ ebx } ; и т. п. Если же var присваивается значение через =, нормальных способов нет. Есть извращения для частных случаев. Что вы хотите сделать?
я хочу рандомизировать имена регистров поэтому: var должно принимать случайное значение на этапе компиляции и видимо всетаки это будет через = я уже понял что нормальных способов нет, поэтому сделал через костыль... твой опробую завтра, мож ченить и получица лучше чем у мну щя
Код (Text): if ~ defined GenerateRandomValue.Seed GenerateRandomValue.Seed = %t end if macro GenerateRandomValue bMask* { GenerateRandomValue.Seed = ((GenerateRandomValue.Seed*214013+2531011) shr 16) and 0xffffffff RandomValue = GenerateRandomValue.Seed and bMask } macro GenerateRandomValueMax bMask* , bMaxValue* { GenerateRandomValue bMask while RandomValue > bMaxValue GenerateRandomValue bMask end while } ;Макрос случайным образом обнуляет регистр eax, edx, ecx и запихивает в стек. macro x_push.imm_value.0 { GenerateRandomValue 11b if RandomValue = 0 zero_reg eax push eax else if RandomValue = 1 zero_reg edx push edx else if RandomValue = 2 zero_reg ecx push ecx else push 0 end if } Хотя GenerateRandomValue.Seed лучше инициализировать по другому, к примеру скриптом перла.
Знаю, что тема слегка старовата, но, когда она появилась, я отложил решение проблемы автора до лучших времён. Лучшие времена настали сегодня (точнее, по моему времени уже вчера). Так что... на случай, если кто-то заглянет сюда в поисках ответа. Очевидно, что для решения исходной задачи необходимо делать подмену имён регистров на стадии препроцессорной обработки. Поэтому никакие директивы контроля ассемблирования (while, repeat, if, знак равенства и т.п.) нам не помогут. В общем, вот макросы, которые потребовались для реализации: Код (Text): macro dispExp delim*,[exp] { common match \exp,exp \{ _rest equ \exp irps sym,\exp \\{ display \\`sym match head tail, _rest \\\{ restore _rest _rest equ tail display delim \\\} \\} restore _rest \} display 13,10 } struc equcalc expr { rept 1 res:expr \{ restore . . equ res \} } struc equmap values { _rest equ values \. match symbols, . \{ irps sym, symbols \\{ \\forward \\local tmp tmp equ match val any, _rest \\\{ restore tmp tmp equ val restore _rest _rest equ any \\\} \\forward sym equ tmp restore tmp \\} \} restore _rest } macro exchange syms*, pos1*, pos2* { define samepos - match p1,pos1 \{ match =p1,pos2 \\{ restore samepos define samepos, + \\} \} match -, samepos \{ before equ between equ after equ _rest equ syms . symsLength equ 0 match \\syms, syms \\{ irps sym, \\syms \\\{ symsLength equcalc symsLength+1 \\\} \\} define matched1 - define matched2 - rept symsLength n:1 \\{ define matched - match =n, pos1 \\\{ restore matched define matched + restore matched1 define matched1 + match sym any,_rest \\\\{ sym1 equ sym \\\\} \\\} match =n, pos2 \\\{ restore matched define matched + restore matched2 define matched2 + match sym any,_rest \\\\{ sym2 equ sym \\\\} \\\} match -, matched \\\{ ;no symbols was still found (before part) match -, matched1 \\\\{ match -, matched2 \\\\\{ match sym any, _rest \\\\\\{ tmp equ before restore before before equ tmp sym restore tmp \\\\\\} \\\\\} \\\\} ;exactly one of the symbols has been found (between part) define onlyonematched + match matched1, matched1 \\\\{ match =matched1, matched2 \\\\\{ restore onlyonematched define onlyonematched - \\\\\} \\\\} match +, onlyonematched \\\\{ match sym any, _rest \\\\\{ tmp equ between restore between between equ tmp sym restore tmp \\\\\} \\\\} restore onlyonematched ;both symbols has already been found (after part) match +, matched1 \\\\{ match +, matched2 \\\\\{ match sym any, _rest \\\\\\{ tmp equ after restore after after equ tmp sym restore tmp \\\\\\} \\\\\} \\\\} \\\} restore matched ;delete current symbol match sym any, _rest \\\{ restore _rest _rest equ any \\\} \\} restore matched2 restore matched1 restore syms syms equ before sym2 between sym1 after restore before,sym1,between,sym2,after,_rest,symsLength \} restore samepos } macro permuteSymbols symlist,permutationNumber { symlistsize equ 0 symlistsizefact equ 1 match \symlist, symlist \{ irps sym, \symlist \\{ symlistsize equcalc symlistsize+1 symlistsizefact equcalc symlistsizefact*symlistsize \\} \} permutation equ 0 permutation equcalc permutationNumber mod symlistsizefact rept symlistsize i:1 \{ \reverse symlistsizefact equcalc symlistsizefact/i tmp equ 0 tmp equcalc permutation/symlistsizefact+1 permutation equcalc permutation mod symlistsizefact exchange symlist,tmp,i restore tmp \} restore symlistsize,symlistsizefact,permutation } macro randomizeRegisters registerList,seed { reglist equ registerList reglistcopy equ registerList permuteSymbols reglistcopy,seed reglist equmap reglistcopy restore reglistcopy,reglist } 1) dispExp выводит на экран через указанный разделитель все символы (в смысле symbols, а не characters), переданные, начиная со второго аргумента. Например, dispExp ' ', y = 17, x = 2*y+(y mod 12) shl 7 выведет на экран строку: y = 17 , x = 2 * y + ( y mod 12 ) shl 7 2) equcalc утилизирует способность препроцессора считать, введённую автором fasm'а, начиная с версии 1.69. Например, x equcalc (x+1) mod 3 инкрементирует... ну в общем, догадаться, вроде, нетрудно. Важно, что эти вычисления будут выполнены на стадии препроцессорной обработки. 3) equmap определяет символы (symbols) из списка слева от макроса соответствующими символами (или их значениями) справа от макроса. Например, reglist equ eax edx reglist equmap edx eax установит везде замену регистра eax на регистр edx и наоборот. 4) exchange принимает список символов первым параметром, а следующими двумя номера символов, которые в этом списке требуется обменять местами. Например, reglist equ eax ebx ecx exchange reglist, 2, 3 заменит значение reglist на eax ecx ebx. 5) permuteSymbols принимает первым параметром список символов, а вторым номер перестановки, которую нужно применить к этому списку. Номер перестановки должен принадлежать интервалу [0, n!-1], где n — число символов в списке. Последняя возможная перестановка совпадает с исходным порядком списка. Например, reglist equ eax ebx ecx permuteSymbols reglist, 5 не изменит список reglist, а reglist equ eax ebx ecx permuteSymbols reglist, 2 заменит значение reglist на ecx eax ebx. 6) Ну и наконец randomizeRegisters аналогично предыдущему макросу принимает список символов и номер перестановки, но устанавливает не новый список, а новые значения каждому из символов, перемешивая те значения, которые символы имели до вызова макроса. Следующий код перемешает регистры, выведет новый соответствующий список регистров на экран и сгенерирует инструкцию nop: Код (Text): randomizeRegisters eax ebx ecx edx esi edi ebp, 127 dispExp ', ', eax ebx ecx edx esi edi ebp xchg ebp,ebp restore eax,ebx,ecx,edx,esi,edi,ebp Можно и все возможные перестановки посмотреть: Код (Text): rept 5040 i:0 { randomizeRegisters eax ebx ecx edx esi edi ebp, i dispExp ', ', eax ebx ecx edx esi edi ebp restore eax,ebx,ecx,edx,esi,edi,ebp } Только предварительно нужно не забыть сообщить компилятору, что ему понадобятся полтора гигабайта памяти для рассчётов. fasmw скорее всего не сможет выделить необходимый объём памяти, поэтому придётся воспользоваться консольной версией компилятора, например, используя какую-нибудь альтернативную IDE. Обидно, но единственная возможность генерации seed'а для рандомизации регистров — %t — обрабатывается на стадии ассемблирования. Одним из вариантов обхода этой неприятности может быть утилизация способности fasm обрабатывать самомодифицирующиеся исходники. Так сказать, совместимость с более высокоуровневой многопроходностью, которая проявляется в том, что он может "компилировать" в файл с исходником. Поэтому лёгким движением регулярного выражения вышеприведенный код превращается в следующий: Код (Text): format binary as "asm" db "macro dispExp delim*,[exp]",13,10 db "{",13,10 db " common match \exp,exp",13,10 db " \{",13,10 db " _rest equ \exp",13,10 db " irps sym,\exp",13,10 db " \\{",13,10 db " display \\`sym",13,10 db " match head tail, _rest",13,10 db " \\\{",13,10 db " restore _rest",13,10 db " _rest equ tail",13,10 db " display delim",13,10 db " \\\}",13,10 db " \\}",13,10 db " restore _rest",13,10 db " \}",13,10 db " display 13,10",13,10 db "}",13,10 db "",13,10 db "struc equcalc expr",13,10 db "{",13,10 db " rept 1 res:expr",13,10 db " \{",13,10 db " restore .",13,10 db " . equ res",13,10 db " \}",13,10 db "}",13,10 db "",13,10 db "struc equmap values",13,10 db "{",13,10 db " _rest equ values \.",13,10 db " match symbols, .",13,10 db " \{",13,10 db " irps sym, symbols",13,10 db " \\{",13,10 db " \\forward",13,10 db " \\local tmp",13,10 db " tmp equ",13,10 db " match val any, _rest",13,10 db " \\\{",13,10 db " restore tmp",13,10 db " tmp equ val",13,10 db " restore _rest",13,10 db " _rest equ any",13,10 db " \\\}",13,10 db " \\forward",13,10 db " sym equ tmp",13,10 db " restore tmp",13,10 db " \\}",13,10 db " \}",13,10 db " restore _rest",13,10 db "}",13,10 db "",13,10 db "macro exchange syms*, pos1*, pos2*",13,10 db "{",13,10 db " define samepos -",13,10 db " match p1,pos1",13,10 db " \{",13,10 db " match =p1,pos2",13,10 db " \\{",13,10 db " restore samepos",13,10 db " define samepos, +",13,10 db " \\}",13,10 db " \}",13,10 db " match -, samepos",13,10 db " \{",13,10 db " before equ",13,10 db " between equ",13,10 db " after equ",13,10 db " _rest equ syms .",13,10 db " symsLength equ 0",13,10 db " match \\syms, syms \\{ irps sym, \\syms \\\{ symsLength equcalc symsLength+1 \\\} \\}",13,10 db " ",13,10 db " define matched1 -",13,10 db " define matched2 -",13,10 db " rept symsLength n:1",13,10 db " \\{",13,10 db " define matched -",13,10 db " match =n, pos1",13,10 db " \\\{",13,10 db " restore matched",13,10 db " define matched +",13,10 db " restore matched1",13,10 db " define matched1 +",13,10 db " match sym any,_rest \\\\{ sym1 equ sym \\\\}",13,10 db " \\\}",13,10 db " match =n, pos2",13,10 db " \\\{",13,10 db " restore matched",13,10 db " define matched +",13,10 db " restore matched2",13,10 db " define matched2 +",13,10 db " match sym any,_rest \\\\{ sym2 equ sym \\\\}",13,10 db " \\\}",13,10 db " match -, matched",13,10 db " \\\{",13,10 db " ;no symbols was still found (before part)",13,10 db " match -, matched1",13,10 db " \\\\{",13,10 db " match -, matched2",13,10 db " \\\\\{",13,10 db " match sym any, _rest",13,10 db " \\\\\\{",13,10 db " tmp equ before",13,10 db " restore before",13,10 db " before equ tmp sym",13,10 db " restore tmp",13,10 db " \\\\\\}",13,10 db " \\\\\}",13,10 db " \\\\}",13,10 db " ;exactly one of the symbols has been found (between part)",13,10 db " define onlyonematched +",13,10 db " match matched1, matched1",13,10 db " \\\\{",13,10 db " match =matched1, matched2",13,10 db " \\\\\{",13,10 db " restore onlyonematched",13,10 db " define onlyonematched -",13,10 db " \\\\\}",13,10 db " \\\\}",13,10 db " match +, onlyonematched",13,10 db " \\\\{",13,10 db " match sym any, _rest",13,10 db " \\\\\{",13,10 db " tmp equ between",13,10 db " restore between",13,10 db " between equ tmp sym",13,10 db " restore tmp",13,10 db " \\\\\}",13,10 db " \\\\}",13,10 db " restore onlyonematched",13,10 db " ;both symbols has already been found (after part)",13,10 db " match +, matched1",13,10 db " \\\\{",13,10 db " match +, matched2",13,10 db " \\\\\{",13,10 db " match sym any, _rest",13,10 db " \\\\\\{",13,10 db " tmp equ after",13,10 db " restore after",13,10 db " after equ tmp sym",13,10 db " restore tmp",13,10 db " \\\\\\}",13,10 db " \\\\\}",13,10 db " \\\\}",13,10 db " \\\}",13,10 db " restore matched",13,10 db " ;delete current symbol",13,10 db " match sym any, _rest",13,10 db " \\\{",13,10 db " restore _rest",13,10 db " _rest equ any",13,10 db " \\\}",13,10 db " \\}",13,10 db " restore matched2",13,10 db " restore matched1",13,10 db " ",13,10 db " restore syms",13,10 db " syms equ before sym2 between sym1 after",13,10 db " restore before,sym1,between,sym2,after,_rest,symsLength",13,10 db " \}",13,10 db " restore samepos",13,10 db "}",13,10 db "",13,10 db "macro permuteSymbols symlist,permutationNumber",13,10 db "{",13,10 db " symlistsize equ 0",13,10 db " symlistsizefact equ 1",13,10 db " match \symlist, symlist",13,10 db " \{",13,10 db " irps sym, \symlist",13,10 db " \\{",13,10 db " symlistsize equcalc symlistsize+1",13,10 db " symlistsizefact equcalc symlistsizefact*symlistsize",13,10 db " \\}",13,10 db " \}",13,10 db " permutation equ 0",13,10 db " permutation equcalc permutationNumber mod symlistsizefact",13,10 db " rept symlistsize i:1",13,10 db " \{",13,10 db " \reverse",13,10 db " symlistsizefact equcalc symlistsizefact/i",13,10 db " tmp equ 0",13,10 db " tmp equcalc permutation/symlistsizefact+1",13,10 db " permutation equcalc permutation mod symlistsizefact",13,10 db " exchange symlist,tmp,i",13,10 db " restore tmp",13,10 db " \}",13,10 db " restore symlistsize,symlistsizefact,permutation",13,10 db "}",13,10 db "",13,10 db "macro randomizeRegisters registerList,seed",13,10 db "{",13,10 db " reglist equ registerList",13,10 db " reglistcopy equ registerList",13,10 db " ",13,10 db " permuteSymbols reglistcopy,seed",13,10 db " reglist equmap reglistcopy",13,10 db "",13,10 db " restore reglistcopy,reglist",13,10 db "}",13,10 db "",13,10 db "randomizeRegisters eax ebx ecx edx esi edi ebp, " seed = %t mod 5040 tenPow = 10000 while tenPow > 1 tenPow = tenPow/10 db seed/tenPow + '0' seed = seed mod tenPow end while db 13,10 db "dispExp ', ', eax ebx ecx edx esi edi ebp",13,10 db "restore eax,ebx,ecx,edx,esi,edi,ebp",13,10 После двойной компиляции в любимом IDE (у меня это двойное нажатие CTRL+F7 в Notepad++ ) получаем вывод вида: edi, eax, ebp, ebx, edx, esi, ecx Пересохраним исходник и опять дважды компилируем. Новый вывод: ecx, ebp, esi, ebx, edi, eax, edx