Вложенные процедуры в Masm32

Тема в разделе "WASM.BEGINNERS", создана пользователем niakris, 10 мар 2011.

  1. niakris

    niakris Дмитрий

    Публикаций:
    0
    Регистрация:
    3 сен 2008
    Сообщения:
    45
    Есть такая процедура
    Код (Text):
    1. OPTION PROLOGUE : NONE
    2. OPTION EPILOGUE : NONE
    3. proc_1 proc
    4.     retn
    5. proc_1 endp
    Возможно ли внутри этой процедуры создать вторую, в которой можно было бы использовать локальные переменные?
    P.S. Пробовал вот так:
    Код (Text):
    1. OPTION PROLOGUE : NONE
    2. OPTION EPILOGUE : NONE
    3. proc_1 proc
    4.     OPTION PROLOGUE : PROLOGUEDEF
    5.     OPTION EPILOGUE : EPILOGUEDEF
    6.     proc_2 proc
    7.     local temp_var  : DWORD
    8.         ret
    9.     proc_2 endp
    10.     retn
    11. proc_1 endp
    но получил ошибку компилятора A2012: PROC, MACRO, or macro repeat directive must precede LOCAL :dntknw:
     
  2. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    Вы не понимаете сути ассемблера. Ассемблер - язык приближенный к машинному коду. Вы можете сделать вызов из одной процедуры - другой. Но другую процедуру "внутри" - это как "поместить внутрь команды сложения парочку умножений". Это вообще извращение - внутри одной процедуры пытаться делать еще одну. По такой логике, retn внешней процедуры никогда не выполнится, м? Что такое OPTION PROLOGUE - вообще не понимаю :dntknw:

    Вы хотите получить что-то вот такое:
    Код (Text):
    1. proc1:
    2. ...
    3. proc2:
    4.      push ebp
    5.      mov ebp, esp
    6.      sub esp, {общий размер локальных переменных}
    7. ...
    8.      leave
    9.      retn
    Ну так и пишите!

    Код (Text):
    1. proc1:          ;Это просто метка для входа в процедуру 1
    2. ...
    3. proc2 proc    ;А это объявление процедуры 2
    4. LOCAL Var123 :DWord
    5. ...
    6. proc2 endp
    Естественно, процедура1 включает в себя все содержимое процедуры2. Завершать ее специально не нужно - завершение общее. К моменту объявления proc2 стек должен быть пуст (сколько клали - столько и вынули). Вот это - логичный для ассемблера подход.
     
  3. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    В плане аппаратной поддержки вложеных процедур можешь попробовать разобрать c инструкцией enter.
    Вот пример:
    Код (Text):
    1. MyVars1 struc
    2.     x1 dd ?
    3.     x2 dd ?
    4. MyVars1 ends
    5. PMY_VARS1 TYPEDEF PTR MyVars1
    6. PPMY_VARS1 TYPEDEF PTR PMY_VARS1
    7. MyVars2 struc
    8.     x1          dd ?
    9.     x2          dd ?
    10.     ppMyVars    PPMY_VARS1 ?
    11. MyVars2 ends
    12. OPTION PROLOGUE    : NONE
    13. OPTION EPILOGUE    : NONE
    14. proc1 proc
    15.     embed_level=0
    16.     enter sizeof MyVars1-4*embed_level,embed_level  ;íóëåâîé óðîâåíü
    17.     mov MyVars1.x1[ebp-sizeof MyVars1],400h
    18.     mov MyVars1.x2[ebp-sizeof MyVars1],500h
    19.     call proc2
    20.     leave
    21.     retn
    22. proc1 endp
    23. proc2 proc
    24.     embed_level=embed_level+1
    25.     enter sizeof MyVars2-4*embed_level,embed_level  ;ïåðâûé óðîâåíü, âñåãî ìîæåò áûòü äî 32 óðîâíåé
    26.     mov eax,MyVars2.ppMyVars[ebp-sizeof MyVars2]
    27.     mov eax,[eax]   ;eax ñòàðîå çíà÷åíèå ebp
    28.     mov ecx,MyVars1.x1[eax-sizeof MyVars1]
    29.     mov edx,MyVars1.x2[eax-sizeof MyVars1]
    30.     ;ecx=400h è edx=500h
    31.     mov MyVars2.x1[ebp-sizeof MyVars2],ecx
    32.     mov MyVars2.x2[ebp-sizeof MyVars2],edx
    33.     embed_level=embed_level-1
    34.     leave
    35.     retn
    36. proc2 endp
    Все переменные только придётся групировать в структуры.
     
  4. niakris

    niakris Дмитрий

    Публикаций:
    0
    Регистрация:
    3 сен 2008
    Сообщения:
    45
    FatMoon, спасибо за совет :)
    proc_1 была сделана процедурой из-за большого количества локальных меток, имена которых повторяются в других местах программы.... так что переименовал все метки и воспользовался вашим советом... :)
     
  5. niakris

    niakris Дмитрий

    Публикаций:
    0
    Регистрация:
    3 сен 2008
    Сообщения:
    45
    s_d_f, хорошее решение... только при размерах процедур ~4000 строк каждая мне кажется читаемость кода будет не очень... :)
     
  6. s_d_f

    s_d_f New Member

    Публикаций:
    0
    Регистрация:
    15 май 2008
    Сообщения:
    342
    Читаемость будет вообщем как сумеешь... :)
    Например proc1 можно немного улучшить следующим образом.
    Код (Text):
    1. proc1 proc
    2. LOCAL mvar1:MyVars1
    3.     embed_level=0
    4.     enter sizeof MyVars1-4*embed_level,embed_level
    5.     mov mvar1.x1,400h
    6.     mov mvar1.x2,500h
    7.     call proc2
    8.     leave
    9.     retn
    10. proc1 endp
    proc2 тоже также можно в порядок привести. Дальше останется пролог и эпилог написать.
     
  7. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.622
    Адрес:
    Russia
    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 ложиться на вас