Windows-та виртуальді жадымен жұмыс істеу



ЖОСПАР

1. Процестің виртуальді жадының күйі
2. Виртуальді жадыны босату және үлестіру, резервтеу.
3. Нақты жадыда виртуаль беттердің бұғатталуы
4. Виртуальді бетке қатынаудың атрибуттарын өзгерту
5. Процесс беттерінің жұмысты жиынын басқару
6. Виртуальді жадының блоктарын көшіру және инициализациялау
7. Жады күйін анықтау
8. Басқа процесте виртуальді жадымен жұмыс
Процестің виртуальді жадының күйі
Windows-та процестің сызықты адресі 32 биттен тұрады және 0х00000000-дан 0XFFFFFFFF-ке дейін аралығында өзгереді. Бұл теориялық түрде процеске 4 Гбайт логикалық жадыға қатынауға рұқсат береді. Windows NT операциялық жүйелерінде 0x00000000-дан 0x7FFFFFFF дейін адрестер диапазонымен бұл жадының екі кіші гигабайты процеске қатынай алады, 0x80000000-ден 0xFFFFFFFF дейінгі адрестер диапазонында екі үлкен гигабайт жүйемен қолданылады. Windows 98 операциялық жүйесінде процеске 2 Гбайт жады қатынауға болатын, операциялық жүйе көрсеткіштер арқылы мәндерді меншіктеуді тексеру үшін 0x00000000-дан 0x0000FFFF-ке дейінгі адрестер диапазонымен жадының тағы 64 кбайт пайдаланады, ескі MS-DOS және Windows 3.1 операциялық жүйелер сәйкестігін қолдау үшін олардың мәндері NULL-ге инициализацияланған.
Windows операциялық жүйелерінде процестің виртуальді адресі сол процестің сызықты адресінен тек сызықты адрестің биттер интерпретациясымен ерекшеленеді.Сондықтан, Windows-ғы әрбір процеске виртуальді жадының екі гигабайтына қатынай алады. Бұл процесс барлық жадыны біруақытта пайдаланады деп айтуға болмайды. Процеске қатынай алатын виртуальді жадының саны физикалық жадының және дискілердің көлеміне байланысты. Виртуальді жадыны қолдануда процесті шектеу үшін биттер кестесінде кейбір биттер мүмкіндікті емес болып белгіленуі мүмкін.
Бұл ескертпелерден кейін процестің виртуальді жадының күйін баяндауға көшеміз. Процестің көз-қарасымен қарағанда виртуальді жадының беттер үш күйдің біреуінде болуы мүмкін:
□ пайдалану үшін бос (free);
□ пайдалану үшін процеске үлестірілген (committed).
□ резервтелген,бірақ процеспен пайдаланылмайды (reserved);
Бұл күйлерді аңығырақ баяндайық. Бастапқыда, процесті іске қосқанда, виртуальді жадының барлық беттері бос болып есептелінеді, программаның өзі жүктелген беттерден басқа. Барлық модульдердің жүктеу адрестерін программаны жөндеу кезінде Visual C++ құру ортасында Debug/Modules меню пунктінде таңдап құруға болады. Виртуальді жадының бос немесе резервтелген беттерін пайдалануға үлестіру үшін процесс VirtualAlloc функциясын шақыру қажет. Бұл функцияның сәтті аяқталуынан кейін процесс оған үлестірілген виртуальді жадыны пайдалана алады.Үшінші күйі виртуальді беттерді резервтелген деп сипаттайды. Бұл виртуальді беттерді ары қарай қолдану үшін процеспен резервтелген және олардың адресін процеспен нақты емес көрсетусіз пайдалану үшін жүйемен берілмейді. Айтып кететін жәйт, виртуальді беттерді резервтеу кезінде нақты жады бұл беттерге бөлінбейді.

Виртуальді жадыны босату және үлестіру, резервтеу.
Виртуальді жадының облысын резервтеу және үлестіру үшін процесс VirtualAlloc функциясын шақыру қажет, ол келесі прототипке ие:
LPVOID VirtualAlloc(
LPVOID lpAddress, // резервтеу және үлестіру үшін облыс
SIZE_T dwSize, // облыс өлшемі
DWORD flAllocationType, // үлестіру типі
DWORD flProtect // қатынауды қорғау типі
) ;
Сәтті аяқталу кезінде бұл функция процеспен үлестірілген немесе резервтелген виртуаль жадының адресін қайтарады, ал сәтсіз аяқтау кезінде кезінде - NULL қайтарады.Мұнда айтып кетейік, егер виртуальді жадыны VirtualAlloc функциясымен үлестіру сәтті аяқталса, онда бөлінген жады автоматты түрде нөльдермен инициализацияланады. Бұл функцияның параметрлерінің тағайындалуын баяндайық.
lpAddress параметрі шақыртылатын программамен орнатылады және резервтеу немесе үлестіргісі келген процесс, виртуальді жадының бастапқы адресін жүйеге көрсетеді.Бұл адрес алдыңда резервтелген және бос виртуальді жадыны көрсетеді. Бұл адресті орнату кезінде келесі жағдайларды айырады:
 виртуальді жадыны резервтеу кезінде бұл адрес жүйемен шекараға дейін 64 Кбайтқа тегістеледі, ол көрсетілген адреске сай келеді;
 алдыңда резервтелген облыстан виртуальді жадыны үлестіру жағдайда, адресі бар виртуальді беттің шекарасына дейін бұл адрес операциялық жүйемен дөңгелектенеді.
 егер IpAddress параметрі Null-ге тең болса, операциялық жүйе виртуальді жадының бастапқы адресін өзі өзгертеді.
dwSize параметрі шақыртылатын программамен орнатылады және үлестіретін немесе резервтелген облысында виртуальді жадының өлшемін байттармен көрсетеді; Егер IpAddress параметрі Null-ге тең болса, онда жүйе бұл шаманы виртуальді беттің үлкен жағына қарай еселеген өлшемге дейін дөңгелектейді. Егер жады нақты адрестер бойынша үлестірілсе, онда бұл жады IpAddress-тен IpAddress+ dwSize диапазонынан байттары бар барлық беттерінен тұрады.
flAllocationType параметрі программамен орнатылады және VirtualAlloc функция орындайтын операция типіне көрсетеді. Бұл параметрдің мәні болып келесі жалаушалардың кез-келген құрамасы болуы мүмкін:
 MEM_COMMIT – программада жадыны үлестіру;
 MEM_RESERVE – физикалық жадының облысын резервтеу;
WINDOWS NT/2000 операциялық жүйесінде бұл параметрде келесі жалаушалар орнатылуы мүмкін:
 MEM_RESET – жады уақытша қолданылмайды;
 MEM_TOP_DOWN – бос адрестердің үлкенінен бастап жадыны үлестіру. Сонымен бірге, WINDOWS 98 операциялық жүйесінде жалауша орнатылу мүмкін:
 MEM_WRITE_WATCH – жазу жүргізілген виртуальді беттердің адрестерін сақтау.

Windows-та виртуальді жадымен жұмыс істеу
ЖОСПАР
1. Процестің виртуальді жадының күйі
2. Виртуальді жадыны босату және үлестіру, резервтеу.
3. Нақты жадыда виртуаль беттердің бұғатталуы
4. Виртуальді бетке қатынаудың атрибуттарын өзгерту
5. Процесс беттерінің жұмысты жиынын басқару
6. Виртуальді жадының блоктарын көшіру және инициализациялау
7. Жады күйін анықтау
8. Басқа процесте виртуальді жадымен жұмыс
Процестің виртуальді жадының күйі
Windows-та процестің сызықты адресі 32 биттен тұрады және 0х00000000-дан 0xffffffff-ке дейін аралығында өзгереді. Бұл теориялық түрде процеске 4 Гбайт логикалық жадыға қатынауға рұқсат береді. Windows NT операциялық жүйелерінде 0x00000000-дан 0x7FFFFFFF дейін адрестер диапазонымен бұл жадының екі кіші гигабайты процеске қатынай алады, 0x80000000-ден 0xFFFFFFFF дейінгі адрестер диапазонында екі үлкен гигабайт жүйемен қолданылады. Windows 98 операциялық жүйесінде процеске 2 Гбайт жады қатынауға болатын, операциялық жүйе көрсеткіштер арқылы мәндерді меншіктеуді тексеру үшін 0x00000000-дан 0x0000FFFF-ке дейінгі адрестер диапазонымен жадының тағы 64 кбайт пайдаланады, ескі MS-DOS және Windows 3.1 операциялық жүйелер сәйкестігін қолдау үшін олардың мәндері NULL-ге инициализацияланған.
Windows операциялық жүйелерінде процестің виртуальді адресі сол процестің сызықты адресінен тек сызықты адрестің биттер интерпретациясымен ерекшеленеді.Сондықтан, Windows-ғы әрбір процеске виртуальді жадының екі гигабайтына қатынай алады. Бұл процесс барлық жадыны біруақытта пайдаланады деп айтуға болмайды. Процеске қатынай алатын виртуальді жадының саны физикалық жадының және дискілердің көлеміне байланысты. Виртуальді жадыны қолдануда процесті шектеу үшін биттер кестесінде кейбір биттер мүмкіндікті емес болып белгіленуі мүмкін.
Бұл ескертпелерден кейін процестің виртуальді жадының күйін баяндауға көшеміз. Процестің көз-қарасымен қарағанда виртуальді жадының беттер үш күйдің біреуінде болуы мүмкін:
пайдалану үшін бос (free);
пайдалану үшін процеске үлестірілген (committed).
резервтелген,бірақ процеспен пайдаланылмайды (reserved);
Бұл күйлерді аңығырақ баяндайық. Бастапқыда, процесті іске қосқанда, виртуальді жадының барлық беттері бос болып есептелінеді, программаның өзі жүктелген беттерден басқа. Барлық модульдердің жүктеу адрестерін программаны жөндеу кезінде Visual C++ құру ортасында DebugModules меню пунктінде таңдап құруға болады. Виртуальді жадының бос немесе резервтелген беттерін пайдалануға үлестіру үшін процесс VirtualAlloc функциясын шақыру қажет. Бұл функцияның сәтті аяқталуынан кейін процесс оған үлестірілген виртуальді жадыны пайдалана алады.Үшінші күйі виртуальді беттерді резервтелген деп сипаттайды. Бұл виртуальді беттерді ары қарай қолдану үшін процеспен резервтелген және олардың адресін процеспен нақты емес көрсетусіз пайдалану үшін жүйемен берілмейді. Айтып кететін жәйт, виртуальді беттерді резервтеу кезінде нақты жады бұл беттерге бөлінбейді.

Виртуальді жадыны босату және үлестіру, резервтеу.
Виртуальді жадының облысын резервтеу және үлестіру үшін процесс VirtualAlloc функциясын шақыру қажет, ол келесі прототипке ие:
LPVOID VirtualAlloc(
LPVOID lpAddress, резервтеу және үлестіру үшін облыс
SIZE_T dwSize, облыс өлшемі
DWORD flAllocationType, үлестіру типі
DWORD flProtect қатынауды қорғау типі
) ;
Сәтті аяқталу кезінде бұл функция процеспен үлестірілген немесе резервтелген виртуаль жадының адресін қайтарады, ал сәтсіз аяқтау кезінде кезінде - NULL қайтарады.Мұнда айтып кетейік, егер виртуальді жадыны VirtualAlloc функциясымен үлестіру сәтті аяқталса, онда бөлінген жады автоматты түрде нөльдермен инициализацияланады. Бұл функцияның параметрлерінің тағайындалуын баяндайық.
lpAddress параметрі шақыртылатын программамен орнатылады және резервтеу немесе үлестіргісі келген процесс, виртуальді жадының бастапқы адресін жүйеге көрсетеді.Бұл адрес алдыңда резервтелген және бос виртуальді жадыны көрсетеді. Бұл адресті орнату кезінде келесі жағдайларды айырады:
# виртуальді жадыны резервтеу кезінде бұл адрес жүйемен шекараға дейін 64 Кбайтқа тегістеледі, ол көрсетілген адреске сай келеді;
# алдыңда резервтелген облыстан виртуальді жадыны үлестіру жағдайда, адресі бар виртуальді беттің шекарасына дейін бұл адрес операциялық жүйемен дөңгелектенеді.
# егер IpAddress параметрі Null-ге тең болса, операциялық жүйе виртуальді жадының бастапқы адресін өзі өзгертеді.
dwSize параметрі шақыртылатын программамен орнатылады және үлестіретін немесе резервтелген облысында виртуальді жадының өлшемін байттармен көрсетеді; Егер IpAddress параметрі Null-ге тең болса, онда жүйе бұл шаманы виртуальді беттің үлкен жағына қарай еселеген өлшемге дейін дөңгелектейді. Егер жады нақты адрестер бойынша үлестірілсе, онда бұл жады IpAddress-тен IpAddress+ dwSize диапазонынан байттары бар барлық беттерінен тұрады.
flAllocationType параметрі программамен орнатылады және VirtualAlloc функция орындайтын операция типіне көрсетеді. Бұл параметрдің мәні болып келесі жалаушалардың кез-келген құрамасы болуы мүмкін:
# MEM_COMMIT - программада жадыны үлестіру;
# MEM_RESERVE - физикалық жадының облысын резервтеу;
Windows NT2000 операциялық жүйесінде бұл параметрде келесі жалаушалар орнатылуы мүмкін:
# MEM_RESET - жады уақытша қолданылмайды;
# MEM_TOP_DOWN - бос адрестердің үлкенінен бастап жадыны үлестіру. Сонымен бірге, Windows 98 операциялық жүйесінде жалауша орнатылу мүмкін:
# MEM_WRITE_WATCH - жазу жүргізілген виртуальді беттердің адрестерін сақтау.
Кейін бұл беттердің адрестерін GetWriteWatch функциясын шақыру арқылы білуге болады. Мұндай беттердің тізімін тазарту ResetWriteWatch функциясы көмегімен алуға болады. Бұл функцияларды қолдану тек Windows 98 операциялық жүйелерінде қолдану мүмкін болғандықтан, біз оларды толық қарастырмаймыз.
flProtect параметрі виртуальді жадының облысында қатынау атрибуттарын орнатады, олар виртуальді жадының беттерімен тек белгілі операцияларды орындауға рұқсат береді. Бұл параметр келесі жалаушалардың құрамасы болуы мүмкін:
# RAGE_READONLY - виртуальді беттерді тек оқуға рұқсат етеді;
# RAGE_READWRITE - виртуальді беттерде оқуға және жазуға рұқсат етеді;
# RAGE_EXECUTE_READ - виртуальді беттерде кодтың орындалуына және оқуына рұқсат етеді;
# RAGE_NOACCESS - виртуальді беттерге қатынау жоқ;
# RAGE_NOCACHE - виртуальді беттерді КЭШ-ке орналастыруға міндетті емес.
Атап кетейік, кодты тек орындату үшін арналған (RAGE_EXECUTE жалаушасы) бетке жазуға немес оқуға тырысу, қатынас құруға қате жібереді (access violation). Бұл қате виртуальді бетке кез-келген қатынас құруда пайда болады, ол RAGE_NOACCESS жалаушасымен белгіленеді.
Windows NT2000 операциялық жүйесінде flProtect параметрінде жалауша орнатылу мүмкін:
# PAGE_GUARD - қорғалынатын бет.
Егер бұл жалауша орнатылса және бетке үндеу жүргізілсе, оқу немес жазу, бәрібір, жүйе бұл жалаушаны босатады және 0x80000001 коды бар EXCEPTION_GUARD_PAGE типті шығаруды қозғайды. Процеске қосымша виртуальді жадыны бөлу керек болса, бұл жалауша пайдаланады.Мысалы, кейбір деректермен жұмысы кезінде процеспен қолданылатын облыстың соңғы виртуальді беті үшін бұл жалаушаны орнатыға болады. Онда бұл бетке қатынауға әрекет жасаған кезде шығару генерирлейді, және деректер үшін виртуальді жады бітетінін процесс біледі. Сонымен бірге, PAGE_GUARD жалаушасы RAGE_NOACCESS жалаушасымен сәйкес пайдалана алмайды.
Виртуальді жадымен жұмыс аяқталғаннан кейін, VirtualFree функциясын пайдаланып оны босату қажет, ол келесі прототипке ие:
bool VirtualFree (
lpvoid lpAddress, виртуальді жады облысының адресі
SIZE_t dwSize, облыс өлшемі
dword dwFreeType операция типі
);
Сәтті аяқталу кезінде бұл функция нөльдік емес мән қайтарады, ал сәтсіз аяқтау кезінде кезінде - False қайтарады. Бұл функцияның параметрлерін баяндау соңғы параметрден бастайық, өйткені оның мәндері алғашқы екі параметрді программа орнататын мәндерге әсер етеді.
dwFreeType параметрі келесі екі жалаушалардың кез-келген құрамасын қабылдау мүмкін:
# MEM_DECOMMIT - виртуальді жадының үлестіруін орындатпау;
# MEM_RELASE - виртуальді жадыны босату.
Егер MEM_DECOMMIT жалаушасы пайдаланса, онда жады босатылмайды, резервтелген күйде қалады. Резервтелген виртуальді жадыны босату үшін, MEM_RELEASE жалаушасын орнату қажет. Жалпы бұл параметрдің мәнін орнатуға байланысты VirtualFree функциясымен жұмыс істейтін жады облысының күйіне сәйкес болуы қажеттілігін атап кету қажет.
IpAddress параметрі облыстың базалық адресіне көрсету қажет, ол үшін үлестіруді немесе босатуды болдыртпау керек. Егер dwFreeType параметрінде MEM_RELEASE жалаушасы орнатылса, онда бұл адрес VirtualAlloc функциясы қайтарған адреспен сәйкес келу қажет.
dwSize параметрі үлестіруді болдыртпауды қажет ететін, виртуальді жадының облысының өлшемін байтпен береді. dwFreeType параметрінде MEM_RELEASE жалаушасы орнатылса, онда dwSize параметрінің мәні нөльге тең болу керек.
Енді, VirtualAlloc және VirtualFree функциялардың жұмысын баяндайтын мысалдарға көшейік. Алдымен, 21.1-листингтегі программаны қарастырайық, ол виртуальді жады облысын бүтін сандар массивіне үлестіреді, содан кейін оны босатады. Бұл программада бір сәтті жағдайды атап өтейік. Виртуальді жады облысын лезде үлестіру үшін, IpAddress параметрінің күйін Null мәніне орнатуымыз қажет. Бұл жағдайда виртуальді жады облысының бастапқы адресін процеске үлестіру үшін жүйе өзі анықтайды. Нақты виртуаль адрес бойынша жадыны қалай үлестіретіне 21.2-листингте көрсетіледі.

21.2-листингтегі программада виртуальді жады облысын нақты адрес бойынша қалай үлестіруге болатыны көрсетілген. Атап өтейік, бұл жағдайда flAllocationType параметрінің мәні MEM_RESERVE және MEM_COMMIT жалаушаларының құрамасы ретінде орнатылу қажет. Яғни, жадыны нақты адрес бойынша үлестіру кезінде бұл жады алдын-ала резервтелу қажет, ол VirtualAlloc функциясының бір шақыруымен орындалу қажет.

21.2-листингі. Нақты адрес бойынша виртуальді адресті үлестіру.

21.2-листингтегі программада бір кезге көңіл бөлейік. Біз виртуальді жадының бастапқы адресін 0x00890002 орнатсақ та, жүйе оны бәрібір виртуальді беттің жақын төменгі шекараға дейін, яғни 0x00890000 дейін теңістіреді.
Енді жадыны екі кезеңге үлестірейік. Алдымен виртуальді жадының облысын резервтейміз, ал содан кейін бұл виртуаль жадының қайсібір бөлігін үлестіреміз. Қалай ол жасалатыны - 21.3-листингтегі программада көрсетілген. Бұл программада VirtualFree функциясы виртуаль жады облысының үлестіруін орындатпау үшін де қолданылады.

21.3-листинг. Виртуальді жадының үлестіруі және резервтелуі.

Бұл тараудың қорытындысында, 21.4-листингтегі программаны қарастырайық, ол бетті қорғау күйіне орнатады. Бұл бетке бірінші қатынас құруда жүйе PAGE_GUARD жалаушасын босатады және EXCEPTION_GUARD_PAGE шығаруын генерирлейді. Беттің күйі өзгермейді. Бетке қайталап қатынау қарапайым түрде жүргізіледі, яғни ешқандай шығару генерирленбейді. Атап өтейік, үлестірілген виртуаль жадының бастапқы күйі нөльдермен инициализацияланады. Сонымен бірге, бұл кодтың тек Windows 2000 операциялық жүйесінде жұмыс істейтінін атап кетейік.

21.4-листинг.Виртуаль жадының қорғалынатын бетіне қатынас құру.

Нақты жадыда виртуаль беттердің бұғатталуы
Егер виртуаль жадының қайсібір облысы процеспен жиі пайдаланса, онда жүйеге нақты жадыдан бұл виртуальді беттерді сыртқа жүктеуге тыйым салуға болады, басқаша айтқанда, нақты жадыда бұл виртуальді беттерді жабады және бұғаттайды. Бұл үшін VirtualLock функциясын қолдану қажет, ол келесі прототипке ие:
bool VirtuaiLock (
LPVOID lpAddress, облыс адресі
SIZE_T dwSize облыс өлшемі
) ;

Сәтті аяқталу кезінде бұл функция нөльдік емес мән қайтарады, ал сәтсіз аяқтау кезінде кезінде - False қайтарады. IpAddress және dwSize параметрлері сәйкесінше нақты жадыда жабылатын базалық адресті және облыс өлшемін көрсетеді. Атап өтейік, lpAddress-тен IpAddress+ dwSize-ға дейінгі адрестер диапазоны бар барлық виртуаль беттер нақты жадыда жабылады. Мұнда нақты жадыда қатынауға тийым салынған виртуаль беттер жабуға болмайды, яғни олар үшін PAGE_NOACCESS жалауша орнатылады. Сонымен бірге, операциялық жүйе нақты жадыда процеске лезде 30 виртуаль беттен аса бұғаттауға рұқсат бермейді.
Нақты жадыда виртуальді беттерді бұғаттауды болдыртпау үшін VirtualUnlock функциясы қолданылады, ло келесі прототипке ие:
BOOL VirtualUnlock(
... жалғасы

Сіз бұл жұмысты біздің қосымшамыз арқылы толығымен тегін көре аласыз.
Ұқсас жұмыстар
СИ бағдарламалау тілінде жадыны басқару
RISC архитектурасына негізделген процессорлар
Файлдарды көшіруді сұрау
WINDOWS ТИПТІ ОПЕРАЦИЯЛЫҚ ЖҮЙЕЛЕР
СИ тіліндегі динамикалық жады
UNIX операциялық жүйедегі файлдық жүйе
Си бағдарламалау тілінде сызықтық тізімдерді таңдау және іздеу
Сандарды спираль бойынша орналастыру
Аммиакты энерготехнологиялық өндіру процесі
Mac OS X операциялық жүйесі және 10.1Puma нұсқасы
Пәндер