Есть такая процедура Код (Text): OPTION PROLOGUE : NONE OPTION EPILOGUE : NONE proc_1 proc retn proc_1 endp Возможно ли внутри этой процедуры создать вторую, в которой можно было бы использовать локальные переменные? P.S. Пробовал вот так: Код (Text): OPTION PROLOGUE : NONE OPTION EPILOGUE : NONE proc_1 proc OPTION PROLOGUE : PROLOGUEDEF OPTION EPILOGUE : EPILOGUEDEF proc_2 proc local temp_var : DWORD ret proc_2 endp retn proc_1 endp но получил ошибку компилятора A2012: PROC, MACRO, or macro repeat directive must precede LOCAL
Вы не понимаете сути ассемблера. Ассемблер - язык приближенный к машинному коду. Вы можете сделать вызов из одной процедуры - другой. Но другую процедуру "внутри" - это как "поместить внутрь команды сложения парочку умножений". Это вообще извращение - внутри одной процедуры пытаться делать еще одну. По такой логике, retn внешней процедуры никогда не выполнится, м? Что такое OPTION PROLOGUE - вообще не понимаю Вы хотите получить что-то вот такое: Код (Text): proc1: ... proc2: push ebp mov ebp, esp sub esp, {общий размер локальных переменных} ... leave retn Ну так и пишите! Код (Text): proc1: ;Это просто метка для входа в процедуру 1 ... proc2 proc ;А это объявление процедуры 2 LOCAL Var123 :DWord ... proc2 endp Естественно, процедура1 включает в себя все содержимое процедуры2. Завершать ее специально не нужно - завершение общее. К моменту объявления proc2 стек должен быть пуст (сколько клали - столько и вынули). Вот это - логичный для ассемблера подход.
В плане аппаратной поддержки вложеных процедур можешь попробовать разобрать c инструкцией enter. Вот пример: Код (Text): MyVars1 struc x1 dd ? x2 dd ? MyVars1 ends PMY_VARS1 TYPEDEF PTR MyVars1 PPMY_VARS1 TYPEDEF PTR PMY_VARS1 MyVars2 struc x1 dd ? x2 dd ? ppMyVars PPMY_VARS1 ? MyVars2 ends OPTION PROLOGUE : NONE OPTION EPILOGUE : NONE proc1 proc embed_level=0 enter sizeof MyVars1-4*embed_level,embed_level ;íóëåâîé óðîâåíü mov MyVars1.x1[ebp-sizeof MyVars1],400h mov MyVars1.x2[ebp-sizeof MyVars1],500h call proc2 leave retn proc1 endp proc2 proc embed_level=embed_level+1 enter sizeof MyVars2-4*embed_level,embed_level ;ïåðâûé óðîâåíü, âñåãî ìîæåò áûòü äî 32 óðîâíåé mov eax,MyVars2.ppMyVars[ebp-sizeof MyVars2] mov eax,[eax] ;eax ñòàðîå çíà÷åíèå ebp mov ecx,MyVars1.x1[eax-sizeof MyVars1] mov edx,MyVars1.x2[eax-sizeof MyVars1] ;ecx=400h è edx=500h mov MyVars2.x1[ebp-sizeof MyVars2],ecx mov MyVars2.x2[ebp-sizeof MyVars2],edx embed_level=embed_level-1 leave retn proc2 endp Все переменные только придётся групировать в структуры.
FatMoon, спасибо за совет proc_1 была сделана процедурой из-за большого количества локальных меток, имена которых повторяются в других местах программы.... так что переименовал все метки и воспользовался вашим советом...
s_d_f, хорошее решение... только при размерах процедур ~4000 строк каждая мне кажется читаемость кода будет не очень...
Читаемость будет вообщем как сумеешь... Например proc1 можно немного улучшить следующим образом. Код (Text): proc1 proc LOCAL mvar1:MyVars1 embed_level=0 enter sizeof MyVars1-4*embed_level,embed_level mov mvar1.x1,400h mov mvar1.x2,500h call proc2 leave retn proc1 endp proc2 тоже также можно в порядок привести. Дальше останется пролог и эпилог написать.
niakris да не вопрос пишите нативно param_n = 10 yp1 proc push ebp mov ebp,esp sub esp,4*param_n call yp2 pop ebp yp1 endp yp2 proc mov eax,[EPB-4] ; взяли первый локальных параметр от yp1 yp1 endp но ПОМНИТЕ как только вы будете использовать директивы автоматической кодогенерации указать им параметры чтоб вторая процедура не формировала кадр стека и не меняла ebp ложиться на вас