Удобная вещь стек для того, чтобы побродить по лабиринтам с данными. Никогда не заблудишся. Перед поворотом записал, идёшь назад читаешь. Что-то типа клубка Ариадны. Столкнулся с малюсенькой проблемкой. Но сам решал её несколько дней с перерывами Суть: Как увеличить стек у программы. Code (Text): ;goto assemble ; ######################################################################### ; Задача немного увеличить стек у программы. Очень удобно с ним работать. ; ######################################################################### ; ######################################################################### .586 .model flat, stdcall ; 32 bit memory model option casemap :none ; case sensitive include \MASM32\INCLUDE\windows.inc include \MASM32\INCLUDE\masm32.inc include \MASM32\INCLUDE\gdi32.inc include \MASM32\INCLUDE\gdiplus.inc include \MASM32\INCLUDE\user32.inc include \MASM32\INCLUDE\kernel32.inc includelib \MASM32\LIB\masm32.lib includelib \MASM32\LIB\gdi32.lib includelib \MASM32\LIB\gdiplus.lib includelib \MASM32\LIB\user32.lib includelib \MASM32\LIB\kernel32.lib ; ######################################################################### m2m MACRO M1, M2 push M2 pop M1 ENDM .data Prg db "BPP_Orientir.dll",0 ;"Ориентир.exe", 0 hPrg dd 0 _dd dd 0 material dd 0 material_len dd 0 hMemory dd 0 ;------------------------------------------------------------------------------------------------------------- ; Это данные заплаток ---> MyName db " (с) Пархоменко Александр ", 10 dup(" "), 0dh, 0ah, "$", 0 NewStackReserv dd 08000000h NewStackSize dd 04000000h ;------------------------------------------------------------------------------------------------------------- .code ;-------------------------------------------------------------------------------------------------------------------------------- start: invoke CreateFileA, addr Prg, 10000000h, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0 mov hPrg, eax invoke GetFileSize, hPrg, addr _dd ;возвращает в еах а если графика более 4-х гигов то и сюда, будет ли это когда-нибудь ;-) mov material_len, eax invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, material_len ;MEMSIZE mov hMemory,eax invoke GlobalLock, hMemory mov material, eax invoke ReadFile, hPrg, material, material_len, addr _dd, 0 ;_dd = возврат сколько прочитано mov esi, material ; mov dword ptr [esi+04eh], " !iH" mov eax, esi add eax, 04eh invoke lstrcpyA, eax, addr MyName mov dword ptr eax, [esi+03ch] add eax, esi .if word ptr [eax] == "EP" m2m dword ptr [eax+060h], NewStackReserv m2m dword ptr [eax+064h], NewStackSize ;invoke MessageBox, 0, addr Prg, addr Prg, 0 .endif invoke SetFilePointer, hPrg, 0, 0, 0 invoke WriteFile, hPrg, material, material_len, addr _dd, 0 ;_dd = возврат сколько прочитано invoke CloseHandle, hPrg invoke ExitProcess,eax end start ;:assemble ;@echo off ;call \masm32\BIN\BLDALLMY.BAT StackPatch ;exit Просто записываем новые значения размера стека в PE-заголовок. Да можно с памятью подругому разобраться, например выделить хип. Но это не суть важно.
Как видите из исходника, работаем с DLL-кой. И у меня появлялась прелесть типа такого РЕШЕНИЕ: РАЗМЕР СТЕКА DLL НЕ МОЖЕТ БЫТЬ БОЛЬШЕ РАЗМЕРА СТЕКА ВЫЗЫВАЮЩЕЙ ПРОГРАММЫ Правим стек программы и наслаждаемся результатами.
Шо такое "стек DLL"? Стек есть у потока, а больше ни у кого стека не бывает. Вообще, топик ни о чём. Стек увеличивается автоматически операционкой по мере того, как поток пихает туда новые фреймы. Никаких операций с PE заголовком не требуется.
Ursus Стек увеличивается не больше величины поля SizeOfStackReserve из заголовка исполняемого файла. Хотя не спорю, что выводы paralvic — чепуха.
l_inc привет поясни(я не знаю) что точно значит StackReserve и StackCommit, HeapReserve и HeapCommit получится?
edemko Это шуточный вопрос? Что там пояснять-то? Ну ладно... поиграем, посмотрим: SizeOfStackReserve — размер пространства адресов, который будет зарезервирован загрузчиком под стек первичного потока (а также дальнейших потоков в случае выбора дефолтного значения при вызове CreateThread) в виртуальном АП процесса. В случае превышения размера стека этого значения приложение будет закрыто по необработанному исключению доступа к невыделенной памяти. SizeOfStackCommit — объём реальной (сохраняемой и управляемой системой) памяти, которая будет выделена загрузчиком под стек первичного потока (а также дальнейших потоков в случае выбора дефолтного значения при вызове CreateThread) в момент его создания. В случае превышения размера стека этого значения произойдёт исключение доступа к сторожевой странице и в обработчике память будет довыделена и отображена в ранее зарезервированное пространство виртуальных адресов. SizeOfHeapReserve и SizeOfHeapCommit аналогично указывают на зарезервированный и выделенный объём памяти для дефолтной кучи процесса. Сходный механизм, отличающийся в трёх пунктах от вышеописанного: 1) При создании процесса (дефолтная) куча создаётся для всего процесса, а не локально для первичного потока. 2) При создании дальнейших куч, значения по умолчанию не берутся из заголовка исполняемого файла. 3) Расширение объёма памяти, выделенной для (дефолтной) кучи, происходит не по механизму обработки исключения доступа к сторожевой странице (как это сделано для стека), а в случае, если очередной HeapAlloc запросил объём памяти, превышающий объём памяти, выделенный для кучи на момент вызова HeapAlloc.
Да. Тема проще неуда. Но этот факт ограничения размера адресного пространства стека неплохо учитывать, равно как и то чем ограничено адресное пространство, когда подключаешься к процессу, который разрабатывал не ты. Никто ведь не будет спорить, что DLL подключить к инородному процессу проще всего. Или будем настраивать свои релоки и стараться не попасть под чужие.
. Там: полстатьи обсуждение С++ параметра компилятора, ДОС безобразно работал с памятью, а защита сторожевой страницей ограничена и приводит к тому, что мы видим.