Форум: "Основная";
Текущий архив: 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