![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как выделить область в стеке? [D7, WinXP]
HydraMarat © (2005-02-22 17:32:00)Есть ли какая-нибудь функция типа GetMem для стека? Или это в принципе невозможно? Видел в модуле Grids.pas функцию StackAlloc вроде как "декрементирует" SP, но "глобально" она конечно же не работает, только в пределах одной подпрограммы (ну и видимо без вызовов других). Вот, например, C++ умеет же размещать в стеке объекты. Я понимаю, что это на уровне компилятора, но КАК-то же это делается. Может хоть ссылочку на подобное более детальную инфу дадите?
Спасибо.
HydraMarat (2005-02-23 12:10:00) [21]
> Anatoly Podgoretsky
Как это на цифрах сказывается?
Anatoly Podgoretsky (2005-02-23 12:07:00) [22]Это означает выравнивание на границу слова, байта, двойного слова и т.д.
HydraMarat (2005-02-23 12:02:00) [23]Есть еще вопросик: что означает выраванивание по словам, байтам, двойным словам и т.п. В чем суть? Мне когда-то объясняли, но я с этим не работаю и все время забываю. Объясните, плиз, если не сложно (уф) ...
HydraMarat (2005-02-23 11:58:00) [24]
> Германн
Ну подумал и че? Если Вы считаете, что ответ "выучить ассемблер" то, что мне надо, то... Ну давайте большинству спрашивающих отвечать "выучить Delphi"!
Интересно, я посмотрел внимательнее Grids.pas фукнцию StackAlloc и процедурку StackFree... и написано:
{ StackAlloc allocates a 'small' block of memory from the stack by decrementing SP. This provides the allocation speed of a local variable, but the runtime size flexibility of heap allocated memory. }
А потом почитал про то, что "выделение памяти в стеке" - это уменьшение этого самого SP (ESP). Посмотрел CPU View - параметры функцияи API передаются через стек (по крайней мере у тех, что я смотрел). Нельзя было этим ответить? Или Вы все только буквально понимаете? Нельзя привести пример вызова на ассмеблере?
Германн (2005-02-23 03:25:00) [25]2 HydraMarat
Для начала вернись,хотя бы на
HydraMarat (22.02.05 18:59) [14]
И просмотри еще раз два последущих поста [15] и [16].
И еще раз подумай, если сможешь!
Fay (2005-02-23 03:02:00) [26]2 begin...end © (22.02.05 22:17) [28]
...LEAVE/ENTER/LEAVE... ... восстанавливают/сохраняют/восстанавливают...
8)
HydraMarat (2005-02-22 22:18:00) [27]Ладно, "накачал" кучу статеек, видно не все так просто как хотелось (предполагалось). Буду читать, если что назреет - напишу.
Всем спасибо.
begin...end (2005-02-22 22:17:00) [28]> begin...end © (22.02.05 22:12) [27]
> LEAVE/ENTER сохраняют/восстанавливают
ENTER/LEAVE сохраняют/восстанавливают
begin...end (2005-02-22 22:12:00) [29]> HydraMarat (22.02.05 21:49) [24]
> Тогда как же по-значению передавать операнды больших
> размеров?
Ответ очевиден - либо указатели, либо значения по частям.
> Можно подробнее? Или мне лучше за "чтиво" взяться?
Вкратце - LEAVE/ENTER сохраняют/восстанавливают важные регистры (типа EBP) в стеке. За "чтиво" взяться нужно обязательно.
HydraMarat (2005-02-22 22:02:00) [30]
> Набережных С.
И что же Вас оттолкнуло?
Набережных С. (2005-02-22 21:50:00) [31]
> HydraMarat (22.02.05 21:28) [22]
> Я пришел сюда получить ответ.
А я пришел сюда, чтобы, кроме прочего, давать ответы...если у меня возникнет такое желание. Вот Вам отвечать у меня сначала желание было, а потом пропало, уж извините. Но Вы не расстраивайтесь, здесь бывает много грамотных людей, кто-нибудь да поможет. Да уже и помогают.
HydraMarat (2005-02-22 21:49:00) [32]
> begin...end
А вот тот код про PUSH в цикле (допустим соглашение - всё через стек) сработает? И вроде PUSH/POP работает с 16 и 32 битным операндами. Тогда как же по-значению передавать операнды больших размеров? Или их строго через указатели?
> Что же касается команд ENTER и LEAVE, то они пишутся внутри
> подпрограммы. Предназначены они для облегчения написания
> кода пролога/эпилога и автоматически заталкивают/извлекают
> в/из стека содержимое некоторых регистров.
Можно подробнее? Или мне лучше за "чтиво" взяться?
begin...end (2005-02-22 21:32:00) [33]> HydraMarat (22.02.05 21:04) [17]
> Я же сказал: интерпретатор не знает заранее что и как
Интерпретатор должен определить число параметров и запихнуть все параметры в стек или передать параметры через регистры (в случае, если параметров немного). Передать можно по ссылке или по значению - в первом случае запихиваются адреса параметров, во втором - значения параметров. Далее идёт вызов нужной подпрограммы (CALL). Если эта процедура уже написана, то Вам нужно знать, откуда она читает параметры - из стека, из регистров или ещё как-то. Должно быть также известно соглашение о порядке передачи параметров.
Что же касается команд ENTER и LEAVE, то они пишутся внутри подпрограммы. Предназначены они для облегчения написания кода пролога/эпилога и автоматически заталкивают/извлекают в/из стека содержимое некоторых регистров.
HydraMarat (2005-02-22 21:28:00) [34]
> Набережных С.
Может Вы все-таки ответите на мой вопрос? По-подробнее... Я же просто хочу понять в чем я не прав. Я пришел сюда получить ответ.
> Petr V. Abramov
Гм, да CPU View надо посмотреть.
Petr V. Abramov (2005-02-22 21:12:00) [35]> Или мне в цикле?
В принципе лучше сам цикл на ассемблере написать. А что в этом цикле писать - посмотрите в окне cpu код, который генерирует Delphi и почитайте по соглашения о вызовах.
HydraMarat (2005-02-22 21:11:00) [36]
> Набережных С.
Ну ответьте что не так? Как бы Вы осуществили такие действия? Ну и соглашение пусть будет __cdecl
HydraMarat (2005-02-22 21:08:00) [37]Да и еще. Прочел вот про инструкции ENTER и LEAVE. Правильно ли я понял что это и есть то о чем я спросил? Через ENTER выделил, через LEAVE убрал все нафиг... это я про локальные переменные, а не про вызовы...
Набережных С. (2005-02-22 21:07:00) [38]
> HydraMarat (22.02.05 21:04) [17]
Да где уж мне:(
HydraMarat (2005-02-22 21:04:00) [39]
> Набережных С.
Иссяк? Вы так ничего и не ответили на мой вопрос.
> Юрий Зотов
Про PUSH и POP я знаю... И что? Я же сказал: интерпретатор не знает заранее что и как, т.е. изначально я эти инструкции прописать не смогу. Или мне в цикле?
for I := 0 to ParamCount - 1 do
asm
PUSH Params[I]
end;
a потом:
asm
CALL Lib.Name
end;
где Lib.Name - адрес полученный через GetProcAddress?
И давайте без стёба. Считаете что глупость - объясните почему. Считатете что самые умные - ответьте на вопрос.
Юрий Зотов (2005-02-22 19:31:00) [40]> HydraMarat (22.02.05 18:59) [14]
> Интерпретатор (который пишется мною) встречает вызов: F(3, 4);
> Он загружает Lib, находит адрес Name, теперь ей надо передать
> параметры, и вызвать. Как это осуществить?
На псевдоассемблере (чтобы был понятен механизм):
push 3
push 4
call F
В реальности - чуть сложнее, с учетом соглашений о вызове и пр., но схема та же.
И не нужны никакие стековые GetMem. Потому что иначе терятся сам смысл стека.