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

 WASM Phorum —› WASM.ASSEMBLER —› Стек процессора

. 1 . 2 . >>

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


Дата: Июл 7, 2004 16:44:32

Народ, сори, за наивный вопрос. Но тут общался с одним человеком, и теперь у меня ум за разум заходит и цепляется за сомнения. Разъясните мне тупоумному. Стек процессора, с которым мы работаем с помощью push&pop - это структура, которая реализована аппаратно именно в самой микросхеме процессора? Правильно я понимаю? И оперативная память здесь не причем?
Если да, тогда сразу еще вопрос. А какова емкость стека? И что происходит при переполнении?


Дата: Июл 7, 2004 17:42:14

Стек это область оперативной памяти на которую указывают регистры стека.


Дата: Июл 7, 2004 17:44:13

спасибо


Дата: Июл 8, 2004 03:05:05 · Поправил: S_T_A_S_

push & pop можно "разложить на составляющие"
Для 32х разрядного режима так:
  • push src: sub esp, 4 mov [dword ss:esp], src
  • pop dest: mov dest, [dword ss:esp] add esp, 4
Одна оговорка - флаги при push & pop не изменяются.


Дата: Июл 8, 2004 03:26:43

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


Дата: Июл 8, 2004 12:47:47

Sky

не стоит во всём искать смысл. так и ум за разум зайти может !!!!


Дата: Июл 8, 2004 13:18:21

Емкость стэка 4 кб (или одна страница) по умолчанию, если надо больше (никогда не пользовался) кажется надо указать линкеру "Сколько вешать в байтах". Если стартуешь трэд, то в CreateThread есть размер стэка.
При переполнении, в зависимости от Виндов происходтя интересные вещи. Живой пример - в 2000 приложение исчезает бесследно :)


Дата: Июл 8, 2004 13:36:32

S_T_A_S, TheSvin, Chs спасибо за ответы.

А начальное значение ESP устанавливает операционная система при загрузке программы? И выделяет область памяти под стек? Т.е. в исполняемом файле содержится указание ОС сколько памяти необходимо под данные/код/стек и проблема с переполнением стека исключается (Chs, сори, написал до того как увидел твой пост)? Под стек выделяется фиксированное количество памяти (равное максимальному объему данных, помещаемых в стек) или объем памяти под стек меняется во время выполнения программы?


Дата: Июл 8, 2004 13:39:33

CARDINAL, да мне просто интересно.


Дата: Июл 8, 2004 14:19:59

[ Sky: Стек процессора ]

Правильнее называть это стек потока. Поток (thread) - это некая сущьность, которая выполняет код. Стек располагается в оперативной памяти. В режиме пользователя размер стека по умолчанию равен 1Мб. Его можно изменить при компиляции ключом /STACK:[reserve] [,commit].

В PE-заголовке размер (зарезервированный и изначально передаваемый) задан тут:
IMAGE_OPTIONAL_HEADER32 STRUCT
. . .
  SizeOfStackReserve            DWORD      ?
  SizeOfStackCommit             DWORD      ?


Можно указать размер стека и при создании потока функцией CreateThread в параметре dwStackSize. Для получения размера стека в режиме пользователя можно использовать функцию VirtualQuery.

[ Sky: А начальное значение ESP устанавливает операционная система при загрузке программы? ]

Да.

[ Sky: Под стек выделяется фиксированное количество памяти (равное максимальному объему данных, помещаемых в стек) или объем памяти под стек меняется во время выполнения программы? ]

Резервируется фиксированное (см. выше). Изначально выделяется две страницы и по мере необходимости выделяется ещё, но не более зрезервированного размера. При переполнении исключение EXCEPTION_STACK_OVERFLOW.


Для потоков режима ядра размер стека изначально равен 3 страницам (12Кб). Для получения размера стека в режиме ядра можно использовать функции IoGetInitialStack, IoGetStackLimits, IoGetRemainingStackSize.


Дата: Июл 8, 2004 14:38:46

Помещаемые объемы данных Вынь не может расчитать. Надо заранее указать его размер (если не указать ОС выделяет одну страницу). Размер можно прикинуть исходя из размера локальных переменных и то только приблизительно, так как можно не угадать количество обращений к функциям, а там есть пролог функции и если используется рекурсивный вызов, то можно получить Stack Overflow - esp будет указывать на невыделенную память.
Если надо памяти больше, то лучше использовать HeapCreate и т.д. и т.п.
Самый простой выход нашли Бормановские разработчики - сделали стэк мин. 16384 байт и макс. 1048576 байт, а вот как они это сделали, я не знаю (как можно изменять размер стэка)
Как правило если пишешь на АСМе или Си, то 4кб выше крыши.

P.S. Интересно, а как можно изменить на лету размер стэка ?


Дата: Июл 8, 2004 14:46:50

Sorry, читать надо больше...

By default, space is reserved for applications in the following manner:
1 megabyte (MB) reserved (total virtual address space for the stack)
1 page committed (total physical memory allocated when stack is created)

|<--- Total 1 MB for stack --->|<--- Adjacent memory --->|
-------------------------------------------------------- |
| | | |
| 4K | 1020K ... | ... |
| | | |
-------------------------------------------------------- |


Дата: Июл 8, 2004 17:33:25

[ ChS: P.S. Интересно, а как можно изменить на лету размер стэка ? ]

На rsdn.ru была статья про подмену стека. Я уже не помню на лету там или нет стек меняют, но всё равно почитать стОит.


Дата: Июл 9, 2004 10:12:23

Four-F
Ух, спасибо, за столь развернутый ответ!
Хочу прояснить терминологию "Поток (thread)" – это тоже самое, что и "Тред (ветвь)" в 15 уроке Iczelion'a в переводе Aquila?
ChS, а у тебя нет какого-нибудь интересного примера с рекурсивным вызовом функции?

Еще у меня по поводу стека возник такой вопрос. Допустим копирование из памяти в стек. Пусть Var1 и Var2 – это переменные в памяти. Как написал S_T_A_S,
push Var1 – это тождественно:
sub esp, 4
mov [dword ss:esp], Var1
Т.е. фактически мы копируем из памяти в память, но почему тогда не работает
mov Var2, Var1 ?


Дата: Июл 9, 2004 10:55:01

Sky
„но почему тогда не работает
mov Var2, Var1 ?“

Это ограничение формата команды.

. 1 . 2 . >>


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