Макрос Local

Тема в разделе "WASM.BEGINNERS", создана пользователем Sashok, 2 мар 2010.

  1. Sashok

    Sashok New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2009
    Сообщения:
    52
    Здравствуйте.
    Имею проблему,которая мне не понятна.
    Код:
    proc DialProc,hDial,uMsg,wParam,lParam
    local ps PAINTSTRUCT
    local hDC:lol: WORD
    local a:lol: WORD
    local b:lol: WORD
    local hEditP:lol: WORD
    local hEditD:lol: WORD

    push edi esi ebx

    mov eax,[uMsg]
    cmp eax,WM_COMMAND
    je Command
    cmp eax,WM_INITDIALOG
    je Init
    cmp eax,WM_PAINT
    je paint
    cmp eax,WM_CLOSE
    je jCLOSE

    xor eax,eax
    jmp finish
    Init:
    invoke GetDlgItem,[hDial],105
    mov [hEditP],eax
    invoke SetFocus,[hEditP]
    invoke GetDlgItem,[hDial],104
    mov [hEditD],eax
    jmp finish
    paint:
    invoke BeginPaint,[hDial],addr ps
    mov [hDC],eax
    invoke EndPaint,[hDial],addr ps
    jmp finish


    Command:
    mov eax,[wParam]
    cmp ax,123
    je Create

    jmp finish

    Create:
    invoke GetDlgCtrlID,[hEditP]
    mov [a],eax
    invoke GetDlgCtrlID,[hEditD]
    mov ,eax
    invoke GetDlgItemText,[hDial],[a],Buf,5
    invoke SetDlgItemText,[hDial],,Buf
    invoke SetWindowText,[hDial],Buf

    jmp finish




    jCLOSE:



    invoke EndDialog,[hDial],0
    mov eax,1

    finish:
    pop ebx esi edi
    ret
    endp

    Эта процедура (а точнее ее часть "Create") начинает правильно работать только после того
    переменные hEditP и hEditD сделать не локальными, а определить в секции DATA( hEditP dd ?
    hEditD dd ? ).
    Скажите пожалуста ,почему локализация этих переменных ошибочна?
     
  2. Blackbeam

    Blackbeam New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2008
    Сообщения:
    960
    локальные переменные - в стеке и стираются после выхода из процедуры, а ведь то что в ней создаёшь должно обновляться виндой , а цикл обновления - разве он использует эту процедуру? вроде не должен

    вроде так

    помню у меня в какой-то програме invoke BeginPaint не работала с локальной переменной, компилятор ошибки не выдавал, всё окей, вот только окно - йок
     
  3. Sashok

    Sashok New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2009
    Сообщения:
    52
    Тоесть вы хотите сказать что мои переменные вычисляются только один раз при получении WM_INITDIALOG,
    а макрос local резервирует место в стеке каждий раз при обращении к DialProc и каждый раз разные адреса.
    Понял.Спасибо за подсказку.
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Sashok
    Даже если адреса и одинаковые, то любая запись в стек после выхода из DialProc будет затирать её локальные переменные. Правило здесь одно: стековые (bzw. локальные) переменные живут не дольше, чем длится одноразовая отработка использующей их процедуры. Новый вызов процедуры — новые локальные переменные. В этом смысл реентерабельного кода.
     
  5. Sashok

    Sashok New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2009
    Сообщения:
    52
    "В этом смысл реентерабельного кода." - это вы сильно сказали.:)
    Но всеравно спасибо .Хоть информация и проста (для кого то),для меня это важно.
    Незная такой простой информации делаеш глупые ошибкиб из за которых тратиш уйму времени.
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Локальные переменные могут быть глобальными, если расположены выше максимального уровня стека, на который поднимается процедура(в сторону дна). Стек ниже текущего Esp свободен и будет освобождён при возврате. Простые локальные переменные находятся в нём.
     
  7. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    И ещё обращение к локальным переменным осуществляется через ebp. Это надо учитывать если вы изменяете этот регистр.