Есть такое трабл - компилятор ругается "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 в функции...?
addr использует eax для работы, соотв. компилятор превратит это в: lea eax, szCmd push eax отсюда вывод - самому использовать для этого другой регистр
Asterix Прежде отправив его на топики, касающиеся соглашения STDCALL вообще вот так можно: Код (Text): Test proc xor eax,eax jmp @F msg db Test,0 @@: invoke MessageBox,eax,addr msg,eax,eax ret Test endp или так: Test proc xor eax,eax push eax ; в стек флаги push eax ; в стек заголовок (будет "Ошибка") call @F ; в стек msg msg db Test,0 @@: push eax ; в стек parent окошко call MessageBox ret Test endp
[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 будет видна извне? мне нужно, чтоб переменная была определена только локально
Ты на ассемблере пишешь или на КуВасике?? Какая переменная? Какая локальная?? Нет такого тут! НЕТУ!!! Есть переменная в стеке и переменная в памяти. Как вы, наверное, знаете, после выхода из хорошей функции стек восстанавливается, т.е. переменные в стеке теряются. Переменные в памяти висят себе и не жужжат. Достучаться до них могут все, кто хочет. Умелый юзер их даже при просмотре текста проги увидеть может прямо в готовом ехешнике. В этом языке НЕТ ограничений. Это всякие высокоуровневые языки следят за программером, как за дитем. В асме все по-взрослому. Суровые ребята пишут суровый код. Не хочешь использовать какую-то переменную нигде кроме этого куска кода - не используй! Следить за этим должен кодер, а не препроцессор компилятора. [offtopic] Ухх.. Что-то меня с этого сока забрало круто.. [/offtopic]
Он наверное хочет в другом куске тоже имя msg использовать. В каком-то ассемблере это было или для макросов ?
Такая фенька в фасме есть. Там переменные в стеке объявляются с префиксом "." Только я этим не пользуюсь и вобще макросы не люблю.
В FASM метки, начинающиеся с точки, считаются локальными по отношению к предыдущей без точки. r3load > Как написАл уже n0p, под локальными данными в асме понимается то, что находится в стеке. Если просто нужно, чтобы не засорялось пространство имён, можно просто добавить имя подпрограммы: Test_msg db "Test",0 Не совсем удобно, но для MASM другого выхода наверное нет (не считая макросов)
nOp "Какая переменная? Какая локальная?? Нет такого тут! НЕТУ!!!" Это ты, наверное, сгоряча.. Все таки речь идет не о программировании в машинных кодах, а об асме, у котрого есть свои соглашения и ограничения. r3load Для начала не мешало бы путать переменные и константы. msg db Test,0 - это определение константы.Для асма идентификатор msg - это просто алиас для обозначения адреса константы. Если мы определяем ее внутри процедуры, то она локальная, в том смысле что идентификатор msg, ссылающийся на Test, валиден только внутри данной процедуры и обращение к нему из другой процедуры должно привести к ошибке. С другой стороны "в этом языке НЕТ ограничений" и если хочется поизвращаться, то можно "достучаться" и до локальной msg из другой подпрограммы, но для этого следует забыть про msg и использовать ее адрес. Для примера, приведенного Asterix: Код (Text): Test proc xor eax,eax jmp @F msg db Test,0 ... можно обратиться к msg как [offset Test+4], если xor и jmp - двухбайтные инструкции. Если же речь идет о переменных, то - "есть переменная в стеке и переменная в памяти". Переменная в стеке - локальная, в том смыле что к ней физически можно обратиться только из данной процедуры или из вложенных в нее процедур, т.к. при выходе из "хорошей функции .. переменные в стеке теряются". Локальные переменные можно объявлять как в примере yureckor или как все "суровые ребята писать свой суровый код", оперируя только с регистром ESP.
n0p > Они могут объявляться и без точки (!), но имена их будут локальными по отношению к функции. Стек и имена меток - это тёплое и круглое .
Обычно все лок. переменные создаются в стеке. А то у вас не переменная а кусок данных - mov msg,.... работать не будет. Никаких префиксов не надо - только указать размер переменной для себя, чтоб туда случайно не засунуть другую переменную, а также уменьшить стек на размер всех лок. переменных.leo прав эти переменные не используются за пределами функции.
zzzyab > Будет это работать. Переменная, вроде бы, именованный кусок данных, по определению. Например, вот так (если я правильно помню синтаксис MASM): mov byte ptr msg, 0 Теперь о пределах видимости имён: Код (Text): Test PROC LOCAL sui:STARTUPINFO LOCAL pi:PROCESS_INFORMATION invoke CreateProcess, eax, ADDR szCmd, eax, eax, 01h, eax, eax, eax, ADDR sui,ADDR pi ret msg db "Test",0 ; <- вот здесь, идентификатор msg будет локальным по отношению к Test Test ENDP msg db "Test",0 ; <- а это другой идентификатор, имеющий глобальную область видимости У этого варианта есть тотже недостаток что и у варианта sensy - код и данные находятся в одном месте, это не очень правильно с точки зрения работы кеша. Лучше бы делать вроде этого: Код (Text): Test PROC LOCAL sui:STARTUPINFO LOCAL pi:PROCESS_INFORMATION invoke CreateProcess, eax, ADDR szCmd, eax, eax, 01h, eax, eax, eax, ADDR sui,ADDR pi ret .data msg db "Test",0 ; <- вот здесь, идентификатор msg будет локальным по отношению к Test .code Test ENDP Пусть меня поправят знатоки MASM, а то я не уверен, что можно секции переопределять внутри PROC. Вообще же, для таких целей (работа со строками) есть отличные макросы от Four-F.
S_T_A_S_ Возможно. Не знаю. Макросами не пользуюсь принципиально. leo Сгоряча, конечно. Но. Асм, как язык, ограничений не имеет никаких. Ограничения имеют его диалекты (TASM, MASM, etc.). Но их легко можно от этих ограничений отучить. Фасм точно можно - проверено. С++ же никак не отучить - там грамматика не позволит. Собсно, на то это и hll, чтобы ограничивать свободу программиста. ) (сейчас в меня полетят банки из-под колы) ))
nOp Вы "хочите банок, их есть у меня". Высоко мы летаем, аж земли не видно. У нас часто элементарные вопросы превращаются в философские дискуссии. Интересно, это делается осознанно или просто из-за того, что искушенные знатоки не понимают детских вопросов. Проанализируй на досуге первоначальный вопрос и данные ответы до и после вступления тяжелой артиллерии. В принципе такой стиль дискуссии намного интересней, чем просто вопрос-ответ. Но вот что о нас подумают и напишут шпионы из краклаба (см.вопрос чайника ).
Мне, в общем-то без разницы, что обо мне думают. Они все-равно думают неправильно. На самом деле, я правда не могу понять детских вопросов. Тупые вопросы я и сам задавать мастер, но не в форум. Есть много людей, которые с интересом выслушабт и пошлют куда надо (к справочнику, а вы что думали?). Но то вопросы ТУПЫЕ. Нормальные вопросы я не задаю, потому что предпочитаю лично докопаться до истины, хотя бы это займет месяц. Во-первых, так лучше запоминается; во-вторых, попутно можно узнать еще много интересного; в-третьих, чем больше знаешь мест, откуда можно почерпнуть инфу - тем лучше. Если надеяться на помощь дяди, ни к чему хорошему это не приведет. Во как я думаю. %)
Проанализируй на досуге первоначальный вопрос и данные ответы до и после вступления тяжелой артиллерии. leo, ты не прав. Важна именно философия. Нет понятия "локальная переменная". Есть понятие "переменная на стеке" и нечего тут воду мутить. Если человек пришел в мир ассемблера, то пусть учится говорить по его законам. n0p, молодец! Все верно!
Вообще-то дело состоит в том, что вызывается 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 не виделся по имени.. как и чтоб как и для других потоков он был локальным, но задавался прямо строкой, а не сначала созданием места для нее и потом занесением, т.е. больше вопрос по синтаксису МАСМ-а...
volodya ACTION: "Смотрит тут на всех вас.. и просто ухахатывается на полу.... " А я всегда говорил: "Мир программирования полон неточных терминов, которые часто употребляются не по месту" А если быть совсем точным: если мы говорим на уровне оператора proc, то понятие ЛОКАЛЬНАЯ ПЕРЕМЕННАЯ - существует. Если мы говорим на уровне МЕТКА - тогда нет. (с) 5 центов Эдмонда.