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

Вниз

Вопрос по Стэку и все что с ним связано.   Найти похожие ветки 

 
Doc   (2003-06-20 13:07) [0]

Подскажите пожалуйста, когда стэк начинает разростаться, при каждом последующем помещении
переменных в стэк адрес стэка возрастает или уменьшается?

Логически кажется, что должен увеличиваться.

Хотя встретил пример, там приводиться следующая структура

Before push(eax)

____$00FF_FFFF
____$00FF_FFFE
____$00FF_FFFD
____$00FF_FFFC
____$00FF_FFFB
____$00FF_FFFA
____//
____$00FF_FFE9
____$00FF_FFE8
=> ESP
____$00FF_FFE7
____$00FF_FFE6
____$00FF_FFE5
____$00FF_FFE4
____$00FF_FFE3
____$00FF_FFE2


After push(eax)

____$00FF_FFFF
____$00FF_FFFE
____$00FF_FFFD
____$00FF_FFFC
____$00FF_FFFB
____$00FF_FFFA
____//
____$00FF_FFE9
____$00FF_FFE8
____$00FF_FFE7
____$00FF_FFE6
____$00FF_FFE5
=> ESP
____$00FF_FFE4
____$00FF_FFE3
____$00FF_FFE2



Вообще где можно подробней узнать о структуре стэка поподробнеe.


 
delphimun   (2003-06-20 13:35) [1]

Почитай Асемблер учебный курс автор В.Ю.Пирогов (там вроде вначале книги про стек подробно написано) или найди уроки обучения Ассемберу там везде про стек очень подробно расписано(что где как да почему)


 
Федя   (2003-06-20 13:53) [2]

Адрес стека уменьшается.
Это было сделанно в архитектуре i86 для программы у которых cs=ds=ss. Так-как стек растет на встречу куче то sp уменьшается


 
Anatoly Podgoretsky   (2003-06-20 14:08) [3]

Про какой конкретно стек идет речь, это чисто логическая стуруктура в одним концои, где реализация может быть любая и не обязательно адресная.


 
Digitman   (2003-06-20 14:13) [4]


> Doc


адрес вершины стека (содержимое регистра [e]sp) всегда уменьшается при помещении на вершину стека очер.значения (в результате явных или неявных операций со стеком)


> Федя



> Это было сделанно в архитектуре i86 для программы у которых
> cs=ds=ss


совершенно не факт.
ибо никакой связи между стековым механизмом как таковым и конкретными значениями сег.регистров в архитектуре i80x86 нет.


> стек растет на встречу куче то sp уменьшается


[e]sp уменьшанется ВНЕ зависимости от опер.системы.
понятие же "куча" имеет определенный смысл лишь в ОС на базе Win32.
в ДОС понятия "куча" не было (несмотря на некоторое, весьма и весьма отдаленное сходство механизмов программных менеджеров памяти), однако стек там как рос вниз, так и по сей день растет)


 
Федя   (2003-06-20 14:32) [5]

2Digitman
>>[e]sp уменьшанется ВНЕ зависимости от опер.системы.
А кто говорил про ОС

>>в ДОС понятия "куча" не было
:)))


 
Федя   (2003-06-20 14:33) [6]

2Digitman
>>[e]sp уменьшанется ВНЕ зависимости от опер.системы.

А кто говорил про ОС

>>в ДОС понятия "куча" не было

:)))

>>однако стек там как рос вниз, так и по сей день растет)

а кто говорит что вверх?


 
Digitman   (2003-06-20 14:41) [7]


> Федя



> А кто говорил про ОС


а кто упомянул термин "куча" ?)

а "как прикажешь понимать тебя, Саид", если в то время как речь идет исключительно о концепции стекового механизма, ты оперируешь термином, не имеющим ничего общего с концепцией , а относящимся как минимум к одной конкретной ОС-платформе ?

))


 
Doc   (2003-06-20 14:44) [8]

Я тут покапался в коде, тоже в принципе понял, что

Push уменьшает указатель стэка, а pop его увеличивает.

Вот такой вопрос возник.

Если у нас максимальный размер стэка $00100000

То при вызове процедуры, в которой в var будет 10 элементов массива типа integer, программа создаст стэк, у которого верхний адрес будет текущая позиция + 10*4 байт или $28, т.е.
и постепенно будет опускаться вниз. Адрес вершины стека окажеться
текущий адрес+$01, а самый последний элемент, который затолкали первым, будет по адресу (текущий адрес+$28).

Я правильно понимаю или у меня что-то с головой?

А еще вопрос.

Если мы динамически создаем массив, то я так понял будет просто выделено место для нашей процедуры,

текущий адрес + $100000, а дальше что нам нужно, то мы с этим местом и делаем, но эти адреса я так понял уже будут зарезервированы? или динамически все по другому происходит?

Господа проясните плиз...


 
Doc   (2003-06-20 14:46) [9]


> Anatoly Podgoretsky © (20.06.03 14:08)
> Про какой конкретно стек идет речь, это чисто логическая
> стуруктура в одним концои, где реализация может быть любая
> и не обязательно адресная.


Меня больше интересует адресная реализация.
Про логическую структуру LIFO я знаю.


 
Digitman   (2003-06-20 14:54) [10]


> Doc


ты учитываешь, что при вызове процедуры на вершину стека помещается :

- фактические параметры процедуры (по необходимости. в зависимости от calling convention);
- адрес возврата - в win32 = 4 байта (обязательно);

??


 
Doc   (2003-06-20 15:44) [11]


> ты учитываешь, что при вызове процедуры на вершину стека
> помещается :
>
> - фактические параметры процедуры (по необходимости. в зависимости
> от calling convention);
> - адрес возврата - в win32 = 4 байта (обязательно);
>
> ??


Да, ну и когда все укладывается в вершину стэка,
Параметры процедуры, ret
Размер стэка для каждой процедуры, насколько я понял урезается статически, на столько на сколько требуется.

Т.е. если Max Stack size $100000

При статической компиляции, если потребуется $0000FF, то столько и будет выделено, т.е. структура стэка в данном случае будет не $100000, а меньше.

Тогда почему когда мы создаем огромный массив, сразу компилятор не выдает ошибки, типа StackOverflow, а только когда уже программа выполняется? Если все заталкивается в стэк еще при статической компоновке.

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

Я так понимаю что программа выделяет область памяти для стэка в
$100000 по умолчанию, и если она будет занята допустим на

After push(eax)

____$00FF_FFFF
____$00FF_FFFE
____$00FF_FFFD
____$00FF_FFFC
____$00FF_FFFB
____$00FF_FFFA
____//
____$00FF_FFE9
____$00FF_FFE8
____$00FF_FFE7
____$00FF_FFE6
____$00FF_FFE5
=> ESP
____$00FF_FFE4
____$00FF_FFE3
____$00FF_FFE2

То это уже наша проблема, теряем часть памяти?

И если заполняя уже этот по умолчанию стэк размером $100000
лимит 64K будет привышен, то и с нашим динамическим массивом будет StackOverflow, или динамические массивы как то иначе линкуются и StackOverflow уже невозможен, а возможна нехватка памяти.

Если вы поняли, что я имел ввиду, проясните пожалуйста.


 
Anatoly Podgoretsky   (2003-06-20 15:50) [12]

Адресная реализация делается так, при Push: Pointer +(-) на размер стека элемента, при Pop: Pointer -(+) на размер стека элемента. Стем создается статически или динамически.


 
Digitman   (2003-06-20 15:54) [13]


> Doc



> почему когда мы создаем огромный массив, сразу компилятор
> не выдает ошибки, типа StackOverflow, а только когда уже
> программа выполняется? Если все заталкивается в стэк еще
> при статической компоновке.


вот именно ! при компоновке ! а не при компиляции)
компилятор, зная о размере лок.переменных п/программ, ничего не знает о будущем размере стека, а линкер, зная о требуемом MaxStackSize, ничего не знает о том, каким какие маш.инструкции, созданные компилятором, в каком порядке и как будут использовать будущий стек)


 
Digitman   (2003-06-20 16:11) [14]


> все заталкивается в стэк еще
> > при статической компоновке.


неговори ерунды
фрейм стека для размещения лок.данных п/программы создается динамически, в run-time

обычно в Паскале это делается так :

push ebp
mov ebp, esp
sub esp, размер_фрейма // создаем фрейм
... здесь обращаемся к лок.переменным по смещению во фрейме [ebp - смещение_переменной]
... или обращаемся к параметрам п/программы, если они передавалисть через стек [ebp + размер_адреса_возврата + смещение_параметра]

add esp, размер_фрейма //уничтожаем фрейм
pop ebp


в некоторых компиляторах (особенно - ранних версий) вместо манипуляций с esp и ebp для той же цели применяется пара инструкций enter/leave, но она менее эффективна по производительности и далеко не всегда оптимальна.


 
Doc   (2003-06-20 18:50) [15]

Большое спасибо, с этим разобрался.

Еще вопрос.

При объявлении массива

var Arr:array[1..500] of integer;
i:integer;
begin
for i:=1 to High(Arr) do begin arr[i]:=10; end;
end;

При breakpoint"e установленном на begin, выполняется команда
add esp, $fffff830 и сразу
переходит к циклу for i:=....

А вот если массив например

var Arr:array[1..25000] of integer;
i:integer;
begin
for i:=1 to High(Arr) do begin arr[i]:=10; end;
end;

То на breakpoint"e на begin"e прокручивается цикл и несколько команд

push eax
mov eax, $00000018
add esp,$fffff004
push eax
dec eax
jnz -$0a
mov eax,[esp+$00018000]
add esp,$fffff964

и уже потом идет for i:=....

Кто-нибудь может прокоментировать, что происходит в цикле?
Насколько я понял небольшими кусками выделяются адреса памяти
0012E5AC, а потом EAX $00000017 и уже
0012D5AC, что составляет разницу

$1000 или 4096

Откуда это взялось, объясните пожалуйста, почему не может быть все сделано сразу,
за один проход, как в первом случае, и что 4096 за число такое.


 
Doc   (2003-06-20 20:40) [16]

И еще, можно ли 4096, как то регулировать?



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

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

Наверх





Память: 0.5 MB
Время: 0.009 c
14-7595
Zergling
2003-06-17 06:47
2003.07.03
Русский набор символов в Rave Report


1-7500
PiboDIE
2003-06-21 08:43
2003.07.03
TreeView


1-7408
АлеКо
2003-06-23 08:16
2003.07.03
QReport


14-7672
Palladin
2003-06-16 21:57
2003.07.03
подскажите ссылку на


14-7610
som
2003-06-18 16:48
2003.07.03
Удаление компонент





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский