программирование в masm. начинающему

Тема в разделе "WASM.BEGINNERS", создана пользователем nmn, 7 апр 2006.

  1. nmn

    nmn New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2006
    Сообщения:
    11
    Ассемблером я только начал заниматься, поэтому помогите мне с такой штукой:



    LOCAL wc:WNDCLASSEX

    LOCAL msg:MSG

    LOCAL hwnd:HWND



    mov wc.cbSize,SIZEOF WNDCLASSEX

    mov wc.style, CS_HREDRAW or CS_VREDRAW

    mov wc.lpfnWndProc, OFFSET WndProc

    mov wc.cbClsExtra,NULL

    mov wc.cbWndExtra,NULL

    push hInstance

    pop wc.hInstance

    Вот такой код, вроде не сложно, но объясните мне такие, вещи:

    1. Вот LOCAL что значит. В справочном материале написано, что это резервируется память в стеке. А что будет если я превышу тот размер, который зарезервировал?

    2. Вот есть строчки push ... и pop ... Зачем они сделаны, разве нельзя было сделать mov wc.hInstance,hInstance?

    Вроде пока все вопросы
     
  2. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine


    LOCAL - макрос. Он определяет, что wc, msg и hwnd будут транслироваться препроцессором в конструкцию вида [ebp - XXX], где XXX - определённое число. Если регистр ebp указывает на начало стекового фрейма, то конструкции подобного рода будут указывать на локальные переменные, которые, как известно, хранятся в стеке. Понять принцип стекового фрейма проще всего взглянув на рисунок. "Рисунок" стека можно увидеть в отладчике. OllyDbg для этого идеально подходит.





    Если использовать слишком много места на стеке, то стек может переполниться. Скажем, если Вы создаёте в стеке локальный массив размером в 1Мб, то возможность переполнения следует учитывать. В таком случае процессор сгенерирует исключение и его можно обработать и увеличить размер стека, но по началу лучше просто избегать подобных ситуаций и не выделять на стеке больше 1-2Кб.





    Микроинструкция mov не поддерживает форму, в которой оба операнда указывают на память. Приходится копировать через регистр (eax, edx, ecx, ...) или через стек (push + pop).
     
  3. alex55

    alex55 New Member

    Публикаций:
    0
    Регистрация:
    8 апр 2006
    Сообщения:
    2
    Адрес:
    Russia
    Народ кто знает что надо написать на асме, чтобы вызвать вот такую байду "public: void __thiscall TStringTag::SetValue(char const *)" из DLL ?
     
  4. nmn

    nmn New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2006
    Сообщения:
    11
    Это я опять со стеком. Насколько я знаю в стек значения ложаться как по принципу первым пришел - последним ушел. А здесь что же получается я могу одновременно обращаться и к wc и к msg и hwnd? Как это реализуется, компилятором?
     
  5. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    nmn



    Именно так работают инструкции push/pop. Но стек - это такая же область памяти как и секция данных или секция кода или кусок динамической памяти из хипа. Поэтому к переменной на стеке можно обращаться напрямую, если известен её адрес. Макрос LOCAL, стековый фрейм, пролог и эпилог функции, подсчёт эффективного адреса через регистр ebp (конструкции типа [ebp + XXX]) служат только для того, чтобы получить этот самый адрес.



    К примеру, если esp указывает на верхушку стека, то следующий код:
    Код (Text):
    1. mov eax,[esp + 4]


    помещает в eax то, что лежит в стеке во второй 32-битной ячейке сверху. Т.к. регистр esp имеет "склонность" изменяться с каждым push/pop и другими стековыми операциями, то имеет смысл задействовать ещё один регистр чтобы запомнить начальное значение esp:
    Код (Text):
    1. mov ebp,esp


    Теперь не важно сколько push'ов и pop'ов будет следовать дальше - ebp будет указывать на оригинальную верхушку стека. Поэтому к локальным переменным и к параметрам функций обычно обращаются именно через ebp, а не на прямую через esp. К тому же адресация через esp занимает на 1 байт больше чем через любой другой регистр. Таким образом, "теряя" один регистр (обычно ebp) мы упрощаем код и выигрываем в размере.
    Код (Text):
    1. mov eax,[ebp + 4]


    Занимает 3 байта.
    Код (Text):
    1. mov eax,[esp + 4]


    Занимает 4 байта.

    Фиксация начального значения верхушки стека как бы создаёт локальную версию стека для функции. Это и называют стековым фреймом или кадром (stack frame).
     
  6. nmn

    nmn New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2006
    Сообщения:
    11
    спасибо