Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

OC Windows & OC Linux. Лабораторные работы по курсу «Операционные системы»

.pdf
Скачиваний:
0
Добавлен:
06.09.2026
Размер:
2 Мб
Скачать
те адресного пространства, воспользуйтесь функцией GlobalDosAl­loc:
DWORD WINAPI GlobalDosAlloc(DWORD cbAlloc);
Параметр cbAlloc определяет размер блока в байтах. Старшее слово возвращаемого значения содержит сегментную компоненту адреса реального режима, соответствующего полученному блоку памяти. Это значение может использоваться для доступа к блоку памяти в реальном режиме работы процессора.
Младшее слово возвращаемого значения содержит селектор для доступа к полученному блоку
Для освобождения блока памяти, полученного при помощи функции GlobalDOSAlloc, следует вызвать функцию GlobalDosFree:
UINT WINAPI GlobalDosFree(UINT uSelector);
В качестве параметра uSelector этой функции следует передать селекторную компоненту блока памяти, расположенного в первом мегабайте адресного пространства.
В случае успешного завершения возвращаемое значение равно нулю. При ошибке возвращается селектор, указанный в параметре
uSelector.
1.2.9. Освобождение
Для освобождения глобального блока памяти, полученного от функции GlobalAlloc, вы должны использовать функцию GlobalFree:
HGLOBAL WINAPI GlobalFree(HGLOBAL hglb);
Идентификатор освобождаемого блока передается функции в качестве ее единственного параметра.
Функция возвращает NULL при успешном завершении или зна­чение hglb при ошибке.
Перед освобождением зафиксированных блоков памяти их сле­дует предварительно расфиксировать. Вы можете узнать содержи­мое
счетчика фиксаций блока при помощи функции GlobalFlags,
описанной выше.
глобального блока памяти
в защищенном режиме.
41
Для освобождения памяти, полученной при помощи макроко­манды GlobalAllocPtr, удобно использовать макрокоманду Global-
FreePtr, описанную в файле windowsx.h:
#define GlobalFreePtr(lp) \
| (GlobalUnlockPtr(lp),(BOOL)GlobalFree(GlobalPtrHandle (lp)))
Данная макрокоманда расфиксирует, а затем и освобождает блок памяти, заданный своим логическим адресом.
1.2.10. Фиксирование линейного адреса блока памяти
В некоторых случаях вам необходимо запретить изменение ли­нейного адреса блока памяти, которое выполняется в процессе ремещения. Такое изменение выполняется заменой базового адреса в соответствующем дескрипторе локальной таблицы дескрипторов. В результате при перемещении блока логический адрес остается по­стоянным (так как при перемещении блока ему не присваивается новый дескриптор, а логический адрес состоит из ссылки на деск­риптор, номера запрошенного кольца защиты и смещения), в то время как линейный может изменяться.
Если драйвер какого-либо устройства ввода/вывода работает с линейным адресом буфера, память, отведенная для такого буфера, в некоторых случаях должна быть зафиксирована функцией GlobalFix:
void WINAPI GlobalFix(HGLOBAL hglb);
Параметр функции указывает идентификатор фиксируемого блока памяти.
Как только отпадет необходимость в фиксировании блока памя­ти, его следует расфиксировать, вызвав
void WINAPI GlobalUnfix(HGLOBAL hglb);
Единственный параметр этой функции должен содержать иден­тификатор блока памяти, который будет расфиксирован.
1.3. Локальная динамическая память
Для каждого приложения Windows создается автоматический сегмент данных размером 64 Кбайт, в котором располагаются стати-
функцию GlobalUnfix:
42
пе-
ческие данные, стек и локальная область данных (local heap). Размер стека определяется оператором STACKSIZE в файле определения модуля STACKSIZE 8120.
1.3.1. Получение локального блока памяти
Для получения локального блока памяти вы должны использо­вать функцию LocalAlloc:
HLOCAL WINAPI LocalAlloc(UINT fuAlloc/ UINT cbAlloc);
Параметр fuAlloc определяет тип выделяемой памяти. Размер блока памяти в байтах должен передаваться через параметр cbAlloc.
Функция возвращает идентификатор локального блока или NULL, если Windows не может выделить память указанного объема.
Параметра fuAlloc должен быть указан как логическая комби­нация следующих значений:
Флаг Описание
LMEM_DISCARDABLE Заказывается удаляемый блок памяти.
Этот флаг должен использоваться со­вместно с флагом LMEM_MOVEABLE
памяти
LMEM_FIXED
LMEM_MOVEABLE
Заказывается фиксированный блок па­мяти (в защищенном режиме работы блок памяти будет перемещаемым, даже если он заказан с использованием флага LMEM_FIXED, однако в процессе пере­мещения будет изменяться только ли­нейный адрес, но не логический). Этот флаг несовместим с флагом LMEM_
MOVEABLE
Заказывается перемещаемый блок памя­ти. Логический адрес такого блока мо­жет изменяться в процессе перемеще­ния. Этот флаг несовместим с флагом
LMEM_FIXED
43
LMEM_NOCOMPACT Для удовлетворения запроса памяти не
следует выполнять объединение всех свободных участков памяти в один и удалять блоки памяти, отмеченные как удаляемые
LMEM_NOD1SCARD Для удовлетворения запроса памяти не
следует выполнять объединение всех свободных участков памяти в один
LMEM_ZEROINIT
NONZEROLHND Синоним для LMEM_MOVEABLE
NONZEROLPTR Синоним для LMEM_FIXED
Во все байты блока необходимо запи­сать нулевые значения
LHDN
LPTR
1.3.2 Фиксирование и расфиксирование блока памяти
Для получения доступа к полученному блоку памяти его необ­ходимо зафиксировать, вызвав функцию LocalLock :
void NEAR* WINAPI LocalLock(HLOCAL hloc);
Функция LocalLock фиксирует блок памяти, идентификатор ко­торого передается ей через параметр hloc и возвращает логический адрес зафиксированного блока или NULL, если указанный блок уда­лен или произошла ошибка.
Для каждого блока памяти Windows поддерживает счетчик фиксирования. Этот счетчик увеличивается при вызове функции
LocalLock и уменьшается при расфиксировании блока функцией LocalUnlock:
BOOL WINAPI LocalUnlock(HLOCAL hloc);
Синоним для комбинации флагов LMEM _MOVEABLE и LMEM_ZEROINIT
Синоним для комбинации флагов LMEM _FIXED и LMEM_ZEROINIT
44
Если содержимое счетчика уменьшилось до нуля, функция воз­вращает значение FALSE. В противном случае возвращается TRUE.
1.3.3. Определение идентификатора блока памяти по его адресу
С помощью функции LocalHandle вы можете определить иден­тификатор локального блока памяти:
HLOCAL WINAPI LocalHandle(void NEAR* pvMem);
Параметр pvMem указывает адрес локального блока памяти. Возвращаемое значение содержит идентификатор локального блока памяти. В случае ошибки возвращается нулевое значение.
1.3.4. Работа с удаляемыми блоками памяти
Для получения доступа к удаленному локальному блоку памяти его необходимо восстановить, вызвав функцию LocalReAlloc. Эта функция аналогична функции GlobalReAlloc и позволяет изменить характеристики существующего блока памяти.
Приведем
прототип функции LocalReAlloc :
HLOCAL WINAPI LocalReAlloc(HLOCAL hloc, UINT
cbNewSize, UINT fuAlloc);
Параметр hloc указывает идентификатор восстанавливаемого блока памяти.
При помощи параметра cbNewSize вы должны указать размер блока памяти, причем можно восстановить удаленный блок памяти и изменить его размер одновременно.
Параметр fuAlloc определяет тип восстановленного блок памя­ти. Можно указывать логическую комбинацию следующих флагов:
Флаг Описание
LMEM_DISCARDABLE Если блок памяти был перемещаемый,
то теперь дополнительно он будет и удаляемый. Этот флаг должен использо­ваться совместно с флагом
LMEM_MODIFY
45
LMEM_MODIFY
Выполняется изменение характеристик существующего блока памяти, этот флаг необходимо указывать вместе с флагами
LMEM_DISCARDABLE и LMEM_MOVEABLE
MEM_MOVEABLE
LMEM_NODISCARD
LMEM_ZEROINIT
Если раньше указанный блок памяти был перемещаемым и удаляемым, со­держимое счетчика фиксирования для него равно нулю и новый размер блока указан равным нулю, данный блок будет удален. Если же параметр cbNewSize равен нулю, но блок памяти не является перемещаемым или удаляемым, функ­ция вернет признак ошибки. Для фикси­рованного блока
памяти ненулевой дли­ны данный флаг разрешает перемещение, т.е. преобразует фиксированный блок в перемещаемый.
Блок памяти не может быть удален опе­рационной системой. Этот флаг должен использоваться совместно с флагом
LMEM_MODIFY
Если размер блока памяти увеличивает­ся, во все байты дополнительной памяти необходимо записать нулевые значения. Этот флаг несовместим с флагом
LMEM_MODIFY
Восстановив блок памяти, вы должны зафиксировать его функ-
цией LocalLock и затем восстановить его прежнее содержимое.
1.3.5 Определение характеристик локального блока памяти
Для определения характеристик локального блока памяти пред­назначена функция LocalFlags, аналогичная рассмотренной нами ранее функции GlobalFlags:
UINT WINAPI LocalFlags(HLOCAL hloc);
46
Функция возвращает состояние блока памяти, указанного своим единственным параметром. Младший байт возвращаемого значения содержит содержимое счетчика фиксаций блока памяти. В старшем байте могут быть установлены флаги LMEM_DISCARDABLE и
LMEM_DISCARDED.
Если установлен флаг LMEM_DISCARDABLE, проверяемый блок памяти может быть удален Windows в процессе дефрагмен­тации свободной области памяти. Если же установлен флаг
LMEM_DISCARDED, удаление блока памяти
уже произошло.
1.3.6. Определение размера блока памяти
С помощью функции LocalSize вы можете определить размер блока памяти по его идентификатору:
UINT WINAPI LocalSize(HLOCAL hloc);
Эта функция возвращает размер блока памяти, идентификатор которого задан параметром hloc. Если указанный блок памяти не существует или удален, возвращается нулевое значение.
1.3.7. Дефрагментация локального блока памяти
Функция LocalCompact выполняет дефрагментацию свободного пространства
в локальной области данных:
UINT WINAPI LocalCompact(UINT uMinFree);
Функция возвращает размер самого большого доступного не­прерывного блока в локальной области памяти, причем, если пара­метр не равен 0 или –1, выполняется дефрагментация памяти и уда­ление блоков, отмеченных как удаляемые. Если параметр функции указан как 0, функция не выполняет дефрагментацию памяти, но возвращает правильное значение с учетом возможного выполнения дефрагментации.
1.3.8. Уменьшение размера локального блока памяти
Для уменьшения размера существующего локального блока па­мяти можно использовать функцию LocalShrink:
UINT WINAPI LocalShrink(HLOCAL hloc, UINT cbNewSize);
47
Параметр hloc указывает идентификатор изменяемого локаль­ного блока памяти. Новые размеры блока памяти задаются парамет­ром cbNewSize.
Возвращаемое значение в случае успеха равно новому размеру блока памяти.
1.3.9. Освобождение локального блока памяти
Для освобождения локального блока памяти, полученного от функции LocalAlloc, вы должны использовать функцию LocalFree:
HLOCAL WINAPI LocalFree(HLOCAL hloc);
Идентификатор освобождаемого блока передается функции в качестве ее
Функция возвращает NULL при успешном завершении или зна­чение hloc при ошибке.
Перед освобождением зафиксированных блоков памяти их сле­дует предварительно расфиксировать.
1.3.10. Инициализация локальной области данных в заданном сегменте
Для создания и инициализации локальной области данных в за­данном сегменте вы можете воспользоваться функцией LocalInit:
BOOL WINAPI LocalInit(UINT uSegment, UINT uStartAddr, UINTuEndAddr);
Параметр uSegment перед вызовом функции идентификатор сегмента, который будет содержать локальную об­ласть данных.
Параметр uStartAddr определяет начальный адрес локальной области данных, а параметр uEndAddr – конечный адрес локальной области данных.
Первые 16 байтов в сегменте данных необходимо зарезервиро­вать для системы.
Статические данные, описанные в приложении Windows с ис­пользованием ключевого слова static или объявленные как
единственного параметра.
должен содержать
1.4. Статическая память
внешние
48
переменные, располагаются в автоматическом сегменте данных при­ложения. Операционная система Windows фиксирует сегмент дан­ных при активизации приложения и расфиксирует его во время пе­реключения на другие приложения. Поэтому логический адрес сег­мента данных может изменяться.
Рекомендуется использовать ближний статический указатель с явным преобразованием типа к LPSTR:
static PSTR pstrDlgName = "MyDlg";
........
hDlg = CreateDialog(hInst, (LPSTR)pstrDlgName / hWndParent, (DLGPROC) lpDialogProc);
В
процессе явного преобразования типа используется текущее содержимое регистра DS, а не то, которое использовалось при за­грузке приложения в память.
1.5. Автоматическая память
Автоматические данные располагаются, как и статические, в ав­томатическом сегменте данных, назначаемым приложению при его загрузке в память. К автоматическим данным относится стек, пара­метры функций и локальные переменные
Размер стека определяется оператором STACKSIZE в файле оп­ределения модуля и не увеличивается автоматически во время рабо­ты приложения.
1.6. Дополнительная память в структуре класса окна
При регистрации класса окна вы можете в поле cbClsExtra структуры WNDCLASS указать размер дополнительной области па­мяти, которая будет зарезервирована в структуре данных, описы­вающей класс окна. значенные для использования всеми окнами, создаваемыми на базе класса.
Для работы с этой дополнительной памятью предназначены функ­ции SetClassWord, SetClassLong, GetClassWord, GetClassLong.
Функция SetClassWord устанавливает в структуре, описываю­щей класс для окна hwnd, новое значение wNewWord, при этом смещение устанавливаемого слова определяется параметром offset:
В эту область можно записать данные, предна-
.
49
WORD WINAPI SetClassWord(HWND hwnd, int offset, WORD wNewWord);
Для параметра offset вы должны использовать значения от нуля до указанного в поле cbClsExtra минус 2 или следующие значения:
Значение Описание
GCW_HBRBACKGROUND Идентификатор кисти для закраши-
вания фона окна
GCW_HCURSOR Идентификатор курсора GCW_HICON Идентификатор пиктограммы
GCW_STYLE Стили окна
С помощью перечисленных выше четырех значений вы можете изменить характеристики класса окна. Эти изменения будут учиты­ваться только для вновь создаваемых окон.
В случае ошибки функция SetClassWord возвращает нулевое значение.
Функция GetClassWord позволяет вам прочитать содержимое слова дополнительной области памяти со смещением offset:
WORD WINAPI GetClassWord(HWND hwnd, int offset);
Для этой функции вы можете использовать те же
значения, что
и для предыдущей, плюс еще два:
Значение Описание
GCW_CBCSLEXTRA
GCW_CBWNDEXTRA
Размер дополнительной области па­мяти в структуре класса окна
Размер дополнительной области па­мяти в структуре окна
GCW_HBRBACKGROUND Идентификатор кисти для закраши-
вания фона окна
GCW_HCURSOR Идентификатор курсора GCW_HICON Идентификатор пиктограммы
GCW_STYLE Стили окна
50