Локальные переменные

Тема в разделе "WASM.ASSEMBLER", создана пользователем r3load, 5 сен 2004.

  1. r3load

    r3load New Member

    Публикаций:
    0
    Регистрация:
    5 сен 2004
    Сообщения:
    5
    Есть такое трабл - компилятор ругается



    "error A2133: register value overwritten by INVOKE"



    на такую последовательность:



    Test PROC



    LOCAL sui:STARTUPINFO

    LOCAL pi:PROCESS_INFORMATION



    invoke CreateProcess, eax, ADDR szCmd, eax, eax, 01h, eax, eax, eax, ADDR sui,ADDR pi



    Test ENDP



    Как сделать так чтоб он не ругался и второй вопрос -

    как скажем локально определить строку

    msg db "Test",0

    в функции...?
     
  2. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Использовать другой регистр из серии ebx, esi, edi
     
  3. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    addr использует eax для работы, соотв. компилятор превратит это в:

    lea eax, szCmd

    push eax

    отсюда вывод - самому использовать для этого другой регистр
     
  4. sensy

    sensy New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    29
    Asterix

    Прежде отправив его на топики, касающиеся соглашения STDCALL





    вообще вот так можно:
    Код (Text):
    1.  
    2. Test proc
    3.   xor  eax,eax
    4.   jmp @F
    5.   msg db Test,0
    6. @@:
    7.   invoke MessageBox,eax,addr msg,eax,eax
    8.   ret
    9. Test endp
    10.  
    11. или так:
    12.  
    13. Test proc
    14.   xor  eax,eax
    15.   push eax    ; в стек флаги
    16.   push eax    ; в стек заголовок (будет "Ошибка")
    17.   call @F     ; в стек msg
    18.   msg db Test,0
    19. @@:
    20.   push eax    ; в стек parent окошко
    21.   call MessageBox
    22.   ret
    23. Test endp
    24.  
    25.  
     
  5. r3load

    r3load New Member

    Публикаций:
    0
    Регистрация:
    5 сен 2004
    Сообщения:
    5
    [Asterix,masquer]

    >addr использует eax для работы, соотв. компилятор >превратит это в:

    >lea eax, szCmd

    >push eax

    >отсюда вывод - самому использовать для этого другой >регистр



    Сенкс, я уже разобрался, нужно было сделать так:



    lea edx,sui ; <--

    lea ebx,pi ; <--

    invoke CreateProcess, eax, ADDR szCmd, eax, eax, 01h, eax, eax, eax, edx, ebx



    [sensy]



    msg db Test,0



    в данном случае msg будет видна извне? мне нужно, чтоб переменная была определена только локально
     
  6. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    .data?

    stroka struc

    db 256 dup(?)

    stroka ends

    ....



    .code

    ... proc

    local msg:stroka

    ...
     
  7. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    Ты на ассемблере пишешь или на КуВасике?? Какая переменная? Какая локальная?? Нет такого тут! НЕТУ!!! Есть переменная в стеке и переменная в памяти. Как вы, наверное, знаете, после выхода из хорошей функции стек восстанавливается, т.е. переменные в стеке теряются. Переменные в памяти висят себе и не жужжат. Достучаться до них могут все, кто хочет. Умелый юзер их даже при просмотре текста проги увидеть может прямо в готовом ехешнике.



    В этом языке НЕТ ограничений. Это всякие высокоуровневые языки следят за программером, как за дитем. В асме все по-взрослому. Суровые ребята пишут суровый код. Не хочешь использовать какую-то переменную нигде кроме этого куска кода - не используй! :) Следить за этим должен кодер, а не препроцессор компилятора.



    [offtopic]

    Ухх.. Что-то меня с этого сока забрало круто..

    [/offtopic]
     
  8. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105




    Он наверное хочет в другом куске тоже имя msg использовать. В каком-то ассемблере это было или для макросов ?
     
  9. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    Такая фенька в фасме есть. Там переменные в стеке объявляются с префиксом "."

    Только я этим не пользуюсь и вобще макросы не люблю.
     
  10. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    В FASM метки, начинающиеся с точки, считаются локальными по отношению к предыдущей без точки.





    r3load >




    Как написАл уже n0p, под локальными данными в асме понимается то, что находится в стеке.

    Если просто нужно, чтобы не засорялось пространство имён, можно просто добавить имя подпрограммы:



    Test_msg db "Test",0



    Не совсем удобно, но для MASM другого выхода наверное нет (не считая макросов)
     
  11. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    nOp

    "Какая переменная? Какая локальная?? Нет такого тут! НЕТУ!!!"

    Это ты, наверное, сгоряча..

    Все таки речь идет не о программировании в машинных кодах, а об асме, у котрого есть свои соглашения и ограничения.



    r3load

    Для начала не мешало бы путать переменные и константы.

    msg db Test,0 - это определение константы.Для асма идентификатор msg - это просто алиас для обозначения адреса константы. Если мы определяем ее внутри процедуры, то она локальная, в том смысле что идентификатор msg, ссылающийся на Test, валиден только внутри данной процедуры и обращение к нему из другой процедуры должно привести к ошибке.

    С другой стороны "в этом языке НЕТ ограничений" и если хочется поизвращаться, то можно "достучаться" и до локальной msg из другой подпрограммы, но для этого следует забыть про msg и использовать ее адрес. Для примера, приведенного Asterix:
    Код (Text):
    1. Test proc
    2.   xor eax,eax
    3.   jmp @F
    4.   msg db Test,0
    5.   ...
    можно обратиться к msg как [offset Test+4], если xor и jmp - двухбайтные инструкции.



    Если же речь идет о переменных, то - "есть переменная в стеке и переменная в памяти". Переменная в стеке - локальная, в том смыле что к ней физически можно обратиться только из данной процедуры или из вложенных в нее процедур, т.к. при выходе из "хорошей функции .. переменные в стеке теряются". Локальные переменные можно объявлять как в примере yureckor или как все "суровые ребята писать свой суровый код", оперируя только с регистром ESP.
     
  12. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    n0p >




    Они могут объявляться и без точки (!), но имена их будут локальными по отношению к функции.

    Стек и имена меток - это тёплое и круглое :).
     
  13. zzzyab

    zzzyab New Member

    Публикаций:
    0
    Регистрация:
    13 май 2004
    Сообщения:
    115
    Обычно все лок. переменные создаются в стеке. А то у вас не переменная а кусок данных - mov msg,.... работать не будет. Никаких префиксов не надо - только указать размер переменной для себя, чтоб туда случайно не засунуть другую переменную, а также уменьшить стек на размер всех лок. переменных.leo прав эти переменные не используются за пределами функции.
     
  14. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    zzzyab >




    Будет это работать. Переменная, вроде бы, именованный кусок данных, по определению.

    Например, вот так (если я правильно помню синтаксис MASM):



    mov byte ptr msg, 0





    Теперь о пределах видимости имён:


    Код (Text):
    1. Test PROC
    2.  
    3. LOCAL sui:STARTUPINFO
    4. LOCAL pi:PROCESS_INFORMATION
    5.  
    6. invoke CreateProcess, eax, ADDR szCmd, eax, eax, 01h, eax, eax, eax, ADDR sui,ADDR pi
    7.  
    8. ret
    9. msg db "Test",0 ; <- вот здесь, идентификатор msg будет локальным по отношению к Test
    10. Test ENDP
    11.  
    12. msg db "Test",0 ; <- а это другой идентификатор, имеющий глобальную область видимости




    У этого варианта есть тотже недостаток что и у варианта sensy - код и данные находятся в одном месте, это не очень правильно с точки зрения работы кеша.



    Лучше бы делать вроде этого:


    Код (Text):
    1. Test PROC
    2.  
    3. LOCAL sui:STARTUPINFO
    4. LOCAL pi:PROCESS_INFORMATION
    5.  
    6. invoke CreateProcess, eax, ADDR szCmd, eax, eax, 01h, eax, eax, eax, ADDR sui,ADDR pi
    7.  
    8. ret
    9. .data
    10. msg db "Test",0 ; <- вот здесь, идентификатор msg будет локальным по отношению к Test
    11. .code
    12. Test ENDP


    Пусть меня поправят знатоки MASM, а то я не уверен, что можно секции переопределять внутри PROC.



    Вообще же, для таких целей (работа со строками) есть отличные макросы от Four-F.
     
  15. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    S_T_A_S_

    Возможно. Не знаю. Макросами не пользуюсь принципиально. :)



    leo

    Сгоряча, конечно. :)

    Но. Асм, как язык, ограничений не имеет никаких. Ограничения имеют его диалекты (TASM, MASM, etc.). Но их легко можно от этих ограничений отучить. Фасм точно можно - проверено. С++ же никак не отучить - там грамматика не позволит. Собсно, на то это и hll, чтобы ограничивать свободу программиста. :)) (сейчас в меня полетят банки из-под колы) :)))
     
  16. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    nOp

    Вы "хочите банок, их есть у меня". Высоко мы летаем, аж земли не видно.

    У нас часто элементарные вопросы превращаются в философские дискуссии. Интересно, это делается осознанно или просто из-за того, что искушенные знатоки не понимают детских вопросов. Проанализируй на досуге первоначальный вопрос и данные ответы до и после вступления тяжелой артиллерии.

    В принципе такой стиль дискуссии намного интересней, чем просто вопрос-ответ. Но вот что о нас подумают и напишут шпионы из краклаба (см.вопрос чайника ).
     
  17. n0p

    n0p 10010000b

    Публикаций:
    0
    Регистрация:
    7 май 2003
    Сообщения:
    256
    Адрес:
    Новосиbeerск
    :)

    Мне, в общем-то без разницы, что обо мне думают. Они все-равно думают неправильно. :)



    На самом деле, я правда не могу понять детских вопросов. Тупые вопросы я и сам задавать мастер, но не в форум. Есть много людей, которые с интересом выслушабт и пошлют куда надо (к справочнику, а вы что думали?). Но то вопросы ТУПЫЕ. Нормальные вопросы я не задаю, потому что предпочитаю лично докопаться до истины, хотя бы это займет месяц. Во-первых, так лучше запоминается; во-вторых, попутно можно узнать еще много интересного; в-третьих, чем больше знаешь мест, откуда можно почерпнуть инфу - тем лучше. Если надеяться на помощь дяди, ни к чему хорошему это не приведет.



    Во как я думаю. %)
     
  18. volodya

    volodya wasm.ru

    Публикаций:
    0
    Регистрация:
    22 апр 2003
    Сообщения:
    1.169
    Проанализируй на досуге первоначальный вопрос и данные ответы до и после вступления тяжелой артиллерии.



    leo, ты не прав.

    Важна именно философия. Нет понятия "локальная переменная". Есть понятие "переменная на стеке" и нечего тут воду мутить. Если человек пришел в мир ассемблера, то пусть учится говорить по его законам.



    n0p, молодец! Все верно!
     
  19. r3load

    r3load New Member

    Публикаций:
    0
    Регистрация:
    5 сен 2004
    Сообщения:
    5
    Вообще-то дело состоит в том, что вызывается CreateThread в котром я хочу чтоб все переменные были локальные для этого потока... вот как..



    .data

    .data?

    .code



    start:

    Mainproc PROC

    CreateThread .. ADDR Test

    ...

    Mainproc ENDP



    Test PROC



    LOCAL msg[100]:BYTE



    blah..



    Test ENDP



    Меня интересовало, можно ли задать параметр msg сразу

    строкой типа msd db "Test",0 и чтоб глобально из

    Mainproc идентификатор msg не виделся по имени.. как и чтоб как и для других потоков он был локальным, но задавался прямо строкой, а не сначала созданием места для нее и потом занесением, т.е. больше вопрос по синтаксису МАСМ-а...
     
  20. Edmond

    Edmond узник замка IF THEN ELSE

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    203
    Адрес:
    WASM.RU
    volodya







    ACTION: "Смотрит тут на всех вас.. и просто ухахатывается на полу.... "



    А я всегда говорил: "Мир программирования полон неточных терминов, которые часто употребляются не по месту"



    А если быть совсем точным: если мы говорим на уровне оператора proc, то понятие ЛОКАЛЬНАЯ ПЕРЕМЕННАЯ - существует. Если мы говорим на уровне МЕТКА - тогда нет.



    (с) 5 центов Эдмонда.