· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Локальные переменные

. 1 . 2 . 3 . 4 . 5 . >>

Посл.отвђт Сообщенiе


Дата: Сен 5, 2004 04:01:47

Есть такое трабл - компилятор ругается

"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
в функции...?


Дата: Сен 5, 2004 04:08:32

Использовать другой регистр из серии ebx, esi, edi


Дата: Сен 5, 2004 05:24:32

addr использует eax для работы, соотв. компилятор превратит это в:
lea eax, szCmd
push eax
отсюда вывод - самому использовать для этого другой регистр


Дата: Сен 5, 2004 09:56:57 · Поправил: sensy

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

„как скажем локально определить строку“
вообще вот так можно:
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



Дата: Сен 5, 2004 11:56:25

[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 будет видна извне? мне нужно, чтоб переменная была определена только локально


Дата: Сен 5, 2004 12:01:19

.data?
stroka struc
db 256 dup(?)
stroka ends
....

.code
... proc
local msg:stroka
...


Дата: Сен 5, 2004 12:22:14

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

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

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


Дата: Сен 5, 2004 13:09:31

„Не хочешь использовать какую-то переменную нигде кроме этого куска кода - не используй! “

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


Дата: Сен 5, 2004 13:34:08

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


Дата: Сен 5, 2004 13:36:48

В FASM метки, начинающиеся с точки, считаются локальными по отношению к предыдущей без точки.


r3load > „как скажем локально определить строку
msg db "Test",0 “


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

Test_msg db "Test",0

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


Дата: Сен 5, 2004 13:40:35

nOp
"Какая переменная? Какая локальная?? Нет такого тут! НЕТУ!!!"
Это ты, наверное, сгоряча..
Все таки речь идет не о программировании в машинных кодах, а об асме, у котрого есть свои соглашения и ограничения.

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

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


Дата: Сен 5, 2004 13:40:37

n0p > „Такая фенька в фасме есть. Там переменные в стеке объявляются с префиксом "." “

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


Дата: Сен 5, 2004 20:57:31

Обычно все лок. переменные создаются в стеке. А то у вас не переменная а кусок данных - mov msg,.... работать не будет. Никаких префиксов не надо - только указать размер переменной для себя, чтоб туда случайно не засунуть другую переменную, а также уменьшить стек на размер всех лок. переменных.leo прав эти переменные не используются за пределами функции.


Дата: Сен 5, 2004 21:42:46 · Поправил: S_T_A_S_

zzzyab > „у вас не переменная а кусок данных - mov msg,.... работать не будет“

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

mov byte ptr msg, 0


Теперь о пределах видимости имён:
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 - код и данные находятся в одном месте, это не очень правильно с точки зрения работы кеша.

Лучше бы делать вроде этого:
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.


Дата: Сен 5, 2004 22:13:29

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

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

. 1 . 2 . 3 . 4 . 5 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.081