Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.03.06;
Скачать: [xml.tar.bz2];

Вниз

Как выделить область в стеке?   Найти похожие ветки 

 
HydraMarat   (2005-02-23 13:30) [40]


> begin...end

К Вам у меня, кстати, претензий нет, от Вас ответ я получил. Ну ладно, к черту все это, никого обидеть не хотел.

По существу. "Выделение памяти" я взял в кавычки, но не исключаю, что вопрос был не совсем корректно сформулирован. Однако, я не писал о размере стека, я писал о резервировании в нем места. Никто же не говорит, что GetMem, образно выражаясь, изменяет физический объем оперативной памяти. Ну и это к черту.

Совсем по существу. Побаловался с ENTER/LEAVE - работает как надо. Набрались еще вопросы, часть может повторится. Можно ответить просто да/нет:

1) Локальные переменные обычно размещают в стеке?
2) Почему параметры для API через стек, а результат в EAX? Это соглашение?
3) Delphi"иские подпрограммы используют __fastcall?
4) Допустим мой интерпретатор тока-тока запускает программу. Могу ли я зарезервировать место в стеке (уменьшить ESP) заранее и просто адресовать его во всех подрограммах, а при их переключениях просто менять содержимое? Для МОИХ естественно данных, а не того что Delphi"ийский компилятор сделает.


 
HydraMarat   (2005-02-23 13:37) [41]

Упс... а ENTER/LEAVE оказывается вообще не нужны! И GetWindowLong и манипуляции с [EBP + N] работают, т.е... блин, а зачем мне тогда ESP уменьшать? Я так понимаю, что если я что-то запишу по отрицательному смещению без изменения ESP, а потом вызову ну пусть все ту же GetWindowLong, то два PUSH"а перед ней затрут то, что я написал в эти отрицательные смещения верно?


 
HydraMarat   (2005-02-23 14:06) [42]

Ээээ... Никто не возражает если я перейду на ТЫ?


 
begin...end ©   (2005-02-23 16:44) [43]

> HydraMarat   (23.02.05 13:30) [40]

> 1) Локальные переменные обычно размещают в стеке?

Не всегда. Вот пример:

function Add: Cardinal;
var
 I, J: Cardinal;
begin
 I := 1;
 J := 2;
 Result := I + J
end


Ставим контрольную точку на выделенной строке, запускаем эту функцию, смотрим в окно CPU и шагаем по F7. Лично я вижу вот что:

B801000000       mov eax,$00000001  <-- первое слагаемое - в EAX
BA02000000       mov edx,$00000002  <-- второе слагаемое - в EDX
03D0             add edx,eax        <-- сложение
8BC2             mov eax,edx        <-- результат - в EAX


Как видите, используются регистры, без стека. Результат возвращается в EAX (последняя строка).

> 2) Почему параметры для API через стек, а результат в
> EAX? Это соглашение?

Через стек - соглашение. Результат в EAX - обычно это так, но, насколько я знаю, не всегда.

> 3) Delphi"иские подпрограммы используют __fastcall?

Согласно моим скромным познаниям в C++, __fastcall - модификатор, используемый для объявления функций, параметры которых должны передаваться через регистры (если они вообще могут быть переданы таким образом). Вот пример передачи параметров через регистры в Delphi:

function MySqr(I: Cardinal): Cardinal;
begin
 Result := I * I
end;

var
 A, B: Cardinal;
begin
 A := 2;
 B := MySqr(A)
end.


Смотрим CPU, начиная с выделенной строки:

BB02000000       mov ebx,$00000002 <-- инициализация переменной A - 2 в EBX
8BC3             mov eax,ebx       <-- подготовка параметра - EBX в EAX
E8EBFFFFFF       call MySqr        <-- вызов супер-пупер функции
8BD0             mov edx,eax       <-- переданный параметр - в EDX
0FAFD0           imul edx,eax      <-- целочисленное умножение: EDX := EDX * EAX
8BC2             mov eax,edx       <-- результат - в EAX
C3               ret               <-- возврат из функции


Таким образом, в данном случае параметры передаются через регистры. В то же время, мы видели, что в других случаях они могут передаваться через стек. Так что - может быть и так, и так. Понятно, что с точки зрения производительности лучше передавать через регистры - они совсем рядом с ядром процессора.

> 4) Допустим мой интерпретатор тока-тока запускает
> программу. Могу ли я зарезервировать место в стеке
> (уменьшить ESP) заранее и просто адресовать его во
> всех подрограммах, а при их переключениях просто
> менять содержимое?

Хм... Честно говоря, я так никогда не делал. Попробуйте, попытка - не пытка. Разумеется, сразу после такого уменьшения ESP нужно сохранить его значение, чтобы потом обращаться по смещениям именно относительно этого значения. Для произвольного доступа к содержимому стека используют, как я уже сказал, базу кадра стека EBP - загрузите туда нужный начальный адрес и попробуйте. Хотя всё же мне не совсем понятно, зачем делать именно так, а не передавать обычным образом (PUSH). Рекомендую Вам задать этот вопрос на форуме по Ассемблеру, например на wasm.ru.


 
Petr V. Abramov ©   (2005-02-23 16:46) [44]

> 1) Локальные переменные обычно размещают в стеке?
 Да
> 2) Почему параметры для API через стек, а результат в EAX? Это соглашение?
 Да
> 3) Delphi"иские подпрограммы используют __fastcall?
 Пусть умные отвечают :)
> 4) Допустим мой интерпретатор тока-тока запускает программу.
> Могу ли я зарезервировать место в стеке (уменьшить ESP) заранее
 Ты заранее знаешь, сколько резервировать? У тебя ж интерпретатор, он не знает, чего и сколько по ходу исполнения программы понадобится. Чем стандартная работа со стеком не устраивает? Ведь не глупые люди ее придумали.


 
Petr V. Abramov ©   (2005-02-23 16:50) [45]

begin...end ©   (23.02.05 16:44) [43]
> Как видите, используются регистры, без стека.
 Нудачный пример. В нем переменные I и J можно заменить константами, что оптимизатор и сделал

Уточнение
>> 2) Почему параметры для API через стек, а результат в EAX? >>Это соглашение?
>> Да
 Конечно, если значение пролезет через регистр :)


 
begin...end ©   (2005-02-23 16:59) [46]

> Petr V. Abramov ©   (23.02.05 16:50) [45]

> Нудачный пример. В нем переменные I и J можно заменить
> константами, что оптимизатор и сделал

Тем не менее, I и J были объявлены как локальные переменные. Что там сделал оптимизатор - это уже другой вопрос.

Более того - замените I := 1 на, скажем, I := Random(3). Дело всё равно ограничится регистрами.


 
Petr V. Abramov ©   (2005-02-23 17:34) [47]

> Тем не менее, I и J были объявлены как локальные переменные
 Так можно так наобъявлять, что их вообще выкинут ;)
 Но обычно - они в стеке :)

 Да в общем-то это дискуссия ни о чем. Что там и как передается - достаточно почитать про соглашения о вызовах, там все четко, а не как у нас на уровне обычно/необычно-лезет/нелезет :)
 Нсчет того, где локальные переменные - да какая по большому счету разница-то. Если ув. HydraMarat задался вопросом, где размещать локальные переменные интрепретируемой программы - так все равно интерпретатору до регистров не добраться, если он жить хочет ;). Остается динамическая память или стек. Лучше динамическая память, распределяемая по образу и подобию стека, через guard page.


 
HydraMarat   (2005-02-23 20:11) [48]

Ух ты! Спасибо, ребят! Вот это то, что я и хотел увидеть :)


> begin...end

Вызов безусловно буду оформлять я (в смысле часть интерпретатора, который запихивает все в стек), поэтому меня интересуют лишь общие моменты. Это действительно вопрос оптимизации.

?
> Хотя всё же мне не совсем понятно, зачем делать именно так,
> а не передавать обычным образом (PUSH)

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


> Petr V. Abramov

> У тебя ж интерпретатор, он не знает, чего и сколько по ходу
> исполнения программы понадобится

Конкретно - не знает. Но в общем, в пред-анализе кода я могу накопить желаемый объем области стека по максимальному количеству локальных переменных, а потом просто перезагружать её при вызовах.


> Лучше динамическая память, распределяемая по образу и подобию
> стека, через guard page

А вот тут подробнее можно? Это же я видел в комментариях к StackAlloc. Что такое guard page?

А где про соглашения почитать? В Windows SDK?

И еще, стек ничто иное как просто "специализированная" область памяти, угу? Так что доступ к ней ничуть не быстрее чем к куче, верно?


 
HydraMarat   (2005-02-23 20:15) [49]


begin...end
> __fastcall

На __fastcall я обратил внимание потому, что много Delphi"йских функций "обмениваются" через стек, а в объявлении обработчиков событий в Borland C++ Builder всегда __fastcall. Только поэтому :)


 
HydraMarat   (2005-02-23 20:19) [50]

Блин, ну что жь я так неаккуратен! Извиняйте. В последнем посте "через стек" надо заменить на "через регистры".


 
Petr V. Abramov ©   (2005-02-23 21:42) [51]

> Что такое guard page?
 См. VirtuaAlloc.
 Но без понимания архитектуры 386+ ничего не поймешь.
 "ПилИте, Шура" :) Не в обиду :)))

> И еще, стек ничто иное как просто "специализированная" область
> памяти, угу? Так что доступ к ней ничуть не быстрее чем к
> куче, верно?
 Верно

> Но в общем, в пред-анализе кода я могу накопить желаемый объем области стека
 Значит, у тебя не совсем интерпретатор, если есть "пред-анализ". В любом случае, это лишний геморрой (если он только для определения р-ра стека).


 
HydraMarat   (2005-02-23 21:59) [52]


> если он только для определения р-ра стека

Уф... ну не также примитивно, естественно. Я проверяю корректность кода, преобразую текстовые данные в двоичные, для скорости и удобства, для сведения возможностей интерпретатора к строго определенному набору действий.


> Но без понимания архитектуры 386+ ничего не поймешь

А что есть это понимание? Почему мне, ничего не объясняя, начинают пилить про "незнание"? Вы объясните. Если что не пойму - спрошу. Вот заладили про архитектуру! Ну что мне нужно расписать про конвейер, про пул инструкций, устройство диспетчеризации/исполнения, сегментацию, страничный механизм и т.п.? Мне это надо было в начале ветки рассказать, чтоб мне просто ответили на вопросы? А еще пишут быть спокойнее... Не в обиду, блин!

То что я хотел я уже узнал. Большое Спасибо товарищам begin...end и Petr V. Abramov.


 
Petr V. Abramov ©   (2005-02-23 22:11) [53]

Про "сегментацию, страничный механизм и т.п." желательно знать как дважды два в шестнадцатеричной системе :)

> Вы объясните. Если что не пойму - спрошу. Вот заладили про архитектуру!
 форум лопнет, если книжки переписывать. Ты оказался в тупике из-за недостатка знаний. Это не позорно, все такими были. Тебе дали направление, что почитать. Если будешь читать, и что-то окажется непонятно - спроси, тебе попытаются растолковать. Но тут же форум, а не изба-читальня, верно?

> Мне это надо было в начале ветки рассказать
 как только стало понятно, что же тебе реально надо, тебе начали рассказывать. Но если мне непонятна ядерная физика, мне ж бесполезно ее объяснять, если я не знаю закон сохранения энергии, верно?


 
HydraMarat   (2005-02-23 22:21) [54]

Учту замечания. с Праздником Всех и до новых встреч :)


 
Petr V. Abramov ©   (2005-02-23 23:10) [55]

> HydraMarat
 Тебя счас еще по формальным грамматикам добрые люди погоняют :)



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2005.03.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.036 c
14-1108700994
begin...end
2005-02-18 07:29
2005.03.06
С Днём рождения! 18 февраля


4-1106055469
Gummer
2005-01-18 16:37
2005.03.06
Hiding the application


14-1108379603
*Pavel
2005-02-14 14:13
2005.03.06
Знатокам советских ОЗУ (на 565 РУ5Д)


1-1109078181
Aleks
2005-02-22 16:16
2005.03.06
как присвоить группе переменных группу данных


14-1108391657
MacroDenS
2005-02-14 17:34
2005.03.06
Загрузочный диск XP





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский