Програмне забезпечення автоматизованих систем

Обсяг оперативної пам'яті комп’ютера, поняття та групи регістрів. Структура процесору та типи даних у ньому, представлення цілих чисел, символів, рядків, адрес. Особливості виконання арифметичних операцій. Загальна модель безпеки в Microsoft Windows NT.

Рубрика Программирование, компьютеры и кибернетика
Вид курс лекций
Язык украинский
Дата добавления 17.06.2010
Размер файла 9,9 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

16*1234h+507h=1234h+507h=12847h

2. Сегментні регістри по домовленості

Згідно описаної схеми сегментування адрес, заміну абсолютних адрес на адресні пари треба виконувати всіма командами які мають операнд-адресу. Але розробники ПК придумали спосіб, який дозволяє уникнути виписування таких пар в більшості команд. Суть його в тому, що заздалегідь домовляються про те, який сегментний регістр на який сегмент пам'яті буде вказувати, і що в командах задається тільки зміщення: не вказаний явно сегментний регістр автоматично відновлюється відповідно цій домовленості. І лише за необхідності порушити цю домовленість потрібно повністю вказувати адресну пару.

Що таке домовленість?

Вважається, що регістр CS завжди вказує на початок області пам'яті, в якій розміщені команди програми (ця область називається сегментом команд або сегментом кодів), і тому при посиланні на клітини цієї області регістр CS можна не вказувати явно, він передбачається по замовчуванню. (Відмутимо, що абсолютна адреса, яка підлягає виконанню, завжди задається парою CS:IP: в лічильнику команд IP завжди знаходиться зміщення цієї команди відповідно адреси із регістра CS.) Аналогічно передбачається, що регістр DS вказує на сегмент даних (область пам'яті з константами, змінними та іншими величинами програми), і тому у всіх посиланнях на цей сегмент регістр DS можна явно не вказувати, т.я. він передбачається по замовчуванню. Регістр SS вказує на стек - область пам'яті, доступ до якої здійснюється за принципом "останній записаний перший прочитаний", і тому всі посилання на стек, в який явно не вказаний сегментний регістр, по замовчуванню сегментуються по регістру SS. Регістр ES вважається вільним, він не прикріплений ні до жодного сегменту пам'яті і його можна використати за власним бажанням; частіше всього він використовується для доступу до даних, які не розмістилися або свідомо не були розміщенні в сегменті даних.

З урахуванням такого розподілу ролей сегментних регістрів машинні програми зазвичай будуються так: всі команди програми розміщуються в одному сегменті памяті, початок якого заноситься в СS, а всі данні розміщуються в іншому сегменті, початок якого заноситься в регістр DS; якщо потрібен стек, то під нього відводиться третій сегмент памяті, початок якого записується в регістр SS. Після цього практично у всіх командах можна вказувати не повні адресні пари, а лише зміщення, т.я. сегментні регістри в цих парах будуть відновлюватися автоматично.

Але тут виникає таке питання: як за зміщенням визначити, на який сегмент памяті воно вказує? В загальних рисах відповідь така: посилання на сегмент команд можуть бути лише в командах переходу, а посилання практично у всіх інших командах (крім рядкових і стекових) - це посилання на сегмент даних. Наприклад, в команді пересилки

MOV AX,X

Імя X сприймається як посилання на дану, а тому автоматично відновлюється за адресною парою DS:X. В команді ж безумовного переходу за адресою, яка знаходиться в регістрі BX,

JMP BX

Абсолютна адреса переходу визначається парою CS:[BX].

Отже, якщо в посиланні на будь-яку клітину памяті не вказаний явний сегментний регістр, то цей регістр береться по замовчуванню. Явно ж сегментні регістри потрібно вказувати, тільки якщо з якихось причин регістр по замовчуванню не підходить. Якщо, наприклад, команді пересилки нам потрібно послатися на стек, тоді нас вже не буде задовольняти домовленість про те, що по замовчуванню операнд команди MOV сегментуються за регістром DS, і тому ми зобов'язані явно вказати інший регістр - в нашому випадку регістр SS, т.я. саме він вказує на стек:

MOV ah,ss:x

Але такі випадки зустрічаються рідко і тому в командах, як правило, вказуються лише зміщення.

Відмітимо, що в MASM сегментний регістр записується в самій команді безпосередньо перед зміщенням (ім'ям змінної, міткою і т.п), Але на рівні машинної мови ситуація дещо інша. Існує 4 спеціальні одно байтові команди, які називаються префіксами заміни сегмента (які позначаються як CS:, DS:, SS: та ES:). Вони ставляться перед командою, операнд-адреса якої повинна бути просегментована по регістру, який відрізняється від регістра, передбаченого по замовчуванню. Наприклад, наведена вище символічна команда пересилки - це дійсно дві машинні команди

SS:

MOV ah,x

3. Сегментування, базування й індексування адрес

Оскільки сегментування адрес - це різновид модифікації адрес, то в ПК адреса, що вказується в команді, у загальному випадку модифікується по трьох регістрах - сегментному, базовому й індексному. У цілому, модифікація адреси виробляється у два етапи. Спочатку враховуються тільки базовий й індексний регістри (якщо вони, звичайно, зазначені в команді), причому обчислення тут відбувається в області 16-бітових адрес; отримана у результаті 16-бітова адреса називається виконавчою (ефективною) адресою. Якщо в команді не передбачене звертання до пам'яті (наприклад, вона завантажує адресу в регістр), то на цьому модифікація адреси закінчується й використається саме виконавча адреса. Якщо ж потрібний доступ до пам'яті, тоді на другому етапі виконавча адреса розглядається як зсув і до нього додається уміст сегментного регістру, зазначеного явно або взятого за замовчуванням, у результаті чого виходить абсолютна (фізична) 20-бітова адреса, по якому реально й відбувається звертання до пам'яті.

Відзначимо, що сегментний регістр ураховується тільки в "останній" момент, безпосередньо перед звертанням до пам'яті, а до цього робота ведеться тільки з 16-бітовими адресами. Якщо врахувати до того ж, що сегментні регістри, як правило, не вказуються в командах, то можна взагалі вважати, що ПК працює з 16-бітовими адресами.

Як уже сказано, якщо в посиланні на комірку пам'яті не зазначений сегментний регістр, то він визначається за замовчуванням. Це робиться по наступним правилам.

1) У командах переходу адреса переходу сегментується по регістру CS і тільки по ньому, тому що абсолютна адреса команди, що повинна бути виконана наступною, завжди визначається парою CS:IP (спроба змінити у таких командах сегментний регістр буде безуспішною).

Відзначимо, що сегментування по регістру CS стосується саме адреси переходу, а не адреси того осередку (комірка або клітина пам'яті), де він може перебувати. Наприклад, в команді безумовного переходу за адресою, що перебуває в осередку X:

JMP X

ім'я X сегментується по регістру DS, а від адреси переходу, взятої з осередку X, уже сегментується по регістру CS.

2) Адреси в усіх інших командах, крім строкових (STOS, MOVS, SCAS й CMPS), за замовчуванням сегментуються:

по регістру DS, якщо серед зазначених регістрів-модифікаторів немає регістра BP;

по регістру SS, якщо один з модифікаторів - регістр BP.

Таким чином, адреси виду A, A[BX], A[SI], A[DI], A[BX][SI] й A[BX][DI] сегментуються по регістру DS, а адреси A[BP], A[BP][SI] й A[BP][DI] - по регістру SS, тобто адреси трьох останніх видів використовуються для доступу до осередків стека.

3) У строкових командах STOS, MOVS, SCAS й CMPS, що мають два операнд-адреса, на які вказують індексні регістри SI й DI, один з операндів (на який указує SI) сегментується по регістру DS, а інший (на нього вказує DI) - по регістру ES.

4. Програмні сегменти. Директива ASSUME

Розглянемо, як сегментування проявляється в програмах на MASM.

Для того щоб вказати, що деяка група команд програми на MASM утворить єдиний сегмент пам'яті, вони оформляються як програмний сегмент: перед ними ставиться директива SEGMENT, після них - директива ENDS, причому на початку обох цих директив повинне бути зазначене одне й те ж ім'я, що грає роль імені сегмента. Програма ж у цілому являє собою послідовність таких програмних сегментів, в кінці якої вказується директива кінця програми END, наприклад:

DT1 SEGMENT ;програмний сегмент з ім'ям DT1

A DB 0

B DW ?

DT1 ENDS;

DT2 SEGMENT ;програмний сегмент DT2

C DB 'hello'

DT2 ENDS;

CODE SEGMENT ;програмний сегмент CODE

ASSUME CS:CODE, DS:DT1, ES:DT2

BEG:

MOV AX,DT2

MOV DS,AX

MOV BH,C

CODE ENDS

END BEG ;кінець тексту програми

Команди програмного сегмента асемблер розміщає в одному сегменті пам'яті (у сукупності вони не повинні займати більше 64Кб) починаючи з найближчої вільної адреси, кратної 16. Номер (перші 16 біт початкової адреси) цього сегменту стає значенням імені сегменту. В MASM це ім'я ставиться до константних виражень, а не адресним, у зв'язку із чим у команді

MOV AX,DT2

другий операнд є безпосереднім, тому в регістр AX буде записано початок (номер) сегменту DT2, а не вміст початкового осередку цього сегменту.

Імена ж змінних (A, B, C) і мітки (BEG) ставляться до адресних виражень, і їм ставиться у відповідність адреса їхнього осередку відносно "свого" сегменту: імені A відповідає адреса 0, імені B - адреса 1, імені C - адреса 0, а мітці BEG - адреса 0.

Всі посилання на команди одного програмного сегмента асемблер сегментує за замовчуванням по тому самому сегментному регістру. По якому саме - встановлюється спеціальною директивою ASSUME. У нашому

прикладі ця директива визначає, що всі посилання на сегмент CODE повинні, якщо явно не зазначений сегментний регістр, сегментуватися по регістру CS, всі посилання на DT1 - по регістру DS, а всі посилання на DT2 - по регістру ES.

Зустрівши в тексті програми посилання на яке-небудь ім'я (наприклад, на ім'я C у команді MOV AX,C), асемблер визначає, у якому програмному сегменті воно описано (у нас - в DT2), потім за інформацією з директиви ASSUME довідається, який сегментний регістр поставлений у відповідність цьому сегменту (у нас - це ES), і далі утворить адресну пару із даного регістра й зсуву імені (у нас - ES:0), що і записує у формульовану машинну команду. При цьому асемблер ураховує використовувану в ПК угоду про сегментні регістри за замовчуванням: якщо в адресній парі, побудованої ним самим або явно заданої в програмі, сегментний регістр збігається з регістром за замовчуванням, то в машинну команду заноситься лише зсув. Якщо, скажемо, у нашому прикладі зустрінеться команда MOV CX,B, тоді по імені В асемблер побудує пари DS:1, але якщо операнд-адрес команди MOV за замовчуванням сегментується по регістру DS, то записувати цей регістр у машинну команду зайво й асемблер записує у неї тільки зсув 1.

Таким чином, директива ASSUME рятує програмістів від необхідності виписувати повні адресні пари не тільки тоді, коли використовуються сегментні регістри за замовчуванням (як у випадку з ім'ям B), але й тоді, коли в машинній команді потрібно було б явно вказати сегментний регістр (як у випадку з ім'ям C). В MASM сегментний регістр у посиланні на ім'я потрібно вказувати лише тоді, коли ім'я повинне по яким-небудь причинам сегментуватися по регістрі, відмінному від того, що поставлено у відповідність всьому сегменту, у якому це ім'я описане.

Однак все це справедливо тільки при дотриманні наступних умов. По-перше, директива ASSUME повинна бути зазначена перед першою командою програми. У іншому випадку асемблер, що переглядає текст програми зверху вниз, не буде знати, як сегментувати імена з команд, розташованих до цієї директиви, і тому зафіксує помилку. По-друге, у директиві ASSUME треба кожному сегменту ставити в відповідність сегментний регістр: якщо асемблеру зустрінеться посилання на ім'я із сегмента, якому не відповідає ніякий сегментний регістр, то він зафіксує помилку. Правда, в обох випадках можна уникнути помилки, але для цього в посиланнях необхідно явно вказувати сегментний регістр.

5. Початкове завантаження сегментних регістрів

Директива ASSUME повідомляє асемблеру про те, по яких регістрах він повинен сегментувати імена з яких сегментів, і "обіцяє", що в цих регістрах будуть перебувати початкові адреси цих сегментів. Однак завантаження цих адрес у регістри сама директива не здійснює. Зробити таке завантаження - обов'язок самої програми, із завантаження сегментних регістрів і повинно починатися виконання програми. Робиться це так.

Оскільки в ПК немає команди пересилання безпосереднього операнда в сегментний регістр (а ім'я, тобто початок, сегменту - це безпосередній операнд), то таке завантаження доводиться робити через якийсь другий, несегментний, регістр (наприклад, AX):

MOV AX,DT1 ;AX:=початок сегмента DT1

MOV DS,AX ;DS:=AX

Аналогічно завантажується й регістр ES.

Завантажувати регістр CS на початку програми не треба: він, як і лічильник команд IP, завантажується операційною системою перед тим, як починається виконання програми (інакше не можна було б почати її виконання). Що ж стосується регістра SS, використовуваного для роботи зі стеком, то він може бути завантажений так само, як і регістри DS й ES, однак в MASM передбачена можливість завантаження цього регістру ще до виконання програми

6. Посилання вперед

Зустрічаючи в символьній команді посилання назад - ім'я, що описане у тексті програми до цієї команди, асемблер уже має необхідну інформацію про ім'я й тому може правильно відтранслювати цю команду. Але якщо в команді зустрінеться посилання вперед, тобто ім'я, що не було описано до команди і яке, напевно, буде описано пізніше, то асемблер у більшості випадків не зможе правильно відтранслювати цю команду. Наприклад, не знаючи, у якому програмному сегменті буде описано це ім'я, асемблер не може визначити, по якому сегментному регістру треба сегментувати ім'я, і тому не може визначити, треба чи ні розміщати перед відповідною машинною командою префікс заміни сегменту а, якщо треба, то який саме.

У подібній ситуації асемблер діє в такий спосіб: якщо в команді зустрілося посилання вперед, то він робить деяке припущення щодо цього імені й уже на основі цього припущення формує машинну команду. Якщо потім (коли зустрінеться опис імені) виявиться, що дане припущення було невірним, тоді асемблер намагається виправити сформульовану ним раніше машинну команду. Однак це не завжди вдається: якщо правильна машинна команда повинна займати більше місця, ніж машинна команда, побудована на основі припущення (наприклад, перед командою треба насправді вставити префікс заміни сегмента), тоді асемблер фіксує помилку (як правило, це помилка номер 6: Phase error between passes.)

Яке ж припущення робить асемблер, зустрічаючи посилання вперед? У всіх командах, крім команд переходу, асемблер припускає, що ім'я буде описано в сегменті даних і тому сегментується по регістру DS. Це варто враховувати при складанні програми: якщо в команді зустрічається посилання вперед на ім'я, що описане в сегменті, на початок якого вказує сегментний регістр, відмінний від DS, то перед таким ім'ям автор програми повинен написати відповідний префікс. Приклад:

code segment

assume cs:code

x dw ?

beg: mov ax,x ;тут замість cs:x можна записати просто x

mov cs:y,ax ;тут обов'язково треба записати cs:y

y dw ?

code ends

Лекція 7

Тема: Операції з рядками

1. Строкові операції

У ПК під рядком розуміється послідовність сусідніх байтів або слів. У зв'язку з цим всі строкові команди мають два різновиди - для роботи з рядками з байтів (у мнемоніку операцій входить буква B) і для роботи з рядками зі слів (у мнемоніку входить W).

Є наступні операції над рядками:

- пересилання елементів рядків ;

- порівняння двох рядків;

- перегляд рядка з метою пошуку елемента, рівного заданому.

Кожна із цих операцій виконується тільки над одним елементом рядка, однак одночасно відбувається автоматичне настроювання на наступний або попередній елемент рядка. Є спеціальні команди повторення (REP й ін.), які змушують наступну за ними строкову команду багаторазово повторюватися (до 2^16 разів), у зв'язку із чим пара команд дозволяє обробити весь рядок, причому набагато швидше, ніж запрограмований цикл.

Крім того, рядок можна переглядати вперед (від їхнього початку до кінця) і назад. Напрямок перегляду залежить від прапора напрямку DF, значення якого можна міняти за допомогою команд STD (DF:=1) і CLD (DF:=0). При DF=0 всі наступні строкові команди програми проглядають рядок вперед, а при DF=1 - назад.

У строкових командах операнди явно не вказуються, а маються на увазі. Якщо команда працює з одним рядком, то адреса чергового, опрацьованого зараз елемента рядка задається парою регістрів DS й SI або парою ES й DI, а якщо команда працює із двома рядками, то адреса елемента однієї з них визначається парою DS:SI, а адреса елемента іншого - парою ES:DI. Після виконання операції значення регістра SI і/або DI збільшується (при DF=0) або зменшується (при DF=1) на 1 (для байтових рядків) або на 2 (для рядків зі слів).

Початкова установка всіх цих регістрів, а також прапора DF повинна бути виконана до початку операції над рядком. Якщо сегментний регістр DS уже має потрібне значення, тоді завантажити регістр SI можна за допомогою команди

LEA SI,<початкова/кінцева адреса рядка>

Якщо ж треба завантажити відразу обидва регістри DS й SI, тоді можна скористатися командою

LDS SI,m32

яка в регістр SI заносить перше слово, а в регістр DS - друге слово з подвійного слова, що має адресу m32 (таким чином, за адресою m32+2 повинен зберігатися сегмент, а за адресою m32 - зсув початкового або кінцевого елемента рядка). Початкове завантаження регістрів ES й DI звичайно здійснюють однією командою

LES DI,m32

яка діє аналогічно команді LDS.

Перелічимо коротенько строкові команди ПК.

Команда завантаження елемента рядка в акумулятор (LODSB або LODSW) пересилає в регістр AL або AX черговий елемент рядка, на який указує пара DS:SI, після чого збільшує (при DF=0) або зменшує (при DF=1) регістр SI на 1 або 2.

Команда запису акумулятора в рядок (STOSB або STOSW) заносить склад регістра AL або AX у той елемент рядка, на який вказує пара ES:DI, після чого змінює регістр DI на 1 або 2.

Команда пересилання рядків (MOVSB або MOVSW) зчитує елемент першого рядка, обумовлений парою DS:SI, в елемент другого рядка, визначений парою ES:DI, після чого одночасно міняє регістри SI й DI.

Команда порівняння рядків (CMPSB або CMPSW) порівнює чергові елементи рядків, що вказуються парами DS:SI й ES:DI, і результат порівняння фіксує в прапорах, після чого міняє регістри SI й DI.

Команда сканування рядка (SCASB або SCASW) порівнює елемент рядка, адреса якого задається парою ES:DI, зі значенням регістра AL або AX і результат порівняння фіксує в прапорах, після чого міняє вміст регістра DI.

Перед будь-якою строковою командою можна поставити одну із двох команд, названих "префіксами повторення", що змусить багаторазово повторитися цю строкову команду. Число повторень (звичайно це довжина рядка) повинне бути зазначене в регістрі CX. Префікс повторення REPZ (синоніми - REPE, REP) спочатку заносить 1 у прапор нуля ZF, після чого, постійно зменшуючи CX на 1, змушує повторюватися наступну за ним строкову команду доти, поки в CX не виявиться 0 або поки прапор ZF не змінить своє значення на 0. Інший префікс повторення REPNZ (синонім - REPNE) діє аналогічно, але тільки спочатку встановлює прапор ZF в 0, а при зміні його на 1 припиняє повторення строкової команди.

Приклад: Нехай треба переписати 10000 байт починаючи з адреси A в інше місце пам'яті починаючи з адреси B. Якщо обоє цих імені ставляться до сегмента даних, на початок якого вказує регістр DS, тоді це пересилання можна зробити так:

CLD ;DF:=0 (перегляд рядка вперед)

MOV CX,1000 ;CX - число повторень

MOV AX,DS

MOV ES,AX ;ES:=DS

LEA SI,A ;ES:SI - "звідки"

LEA DI,B ;DS:DI - "куди"

REP MOVSB ;пересилання CX байтів

Лекція 8

Тема: Стек

1. Стек

У ПК є спеціальні команди роботи зі стеком, тобто областю пам'яті, доступ до елементів якої здійснюється за принципом "останнім записаний - першим прочитаний". Але для того, щоб можна було скористатися цими командами, необхідне дотримання ряду умов.

Під стек можна відвести область у будь-якому місці пам'яті. Розмір її може бути будь-яким, але не повинен перевершувати 64Кб, а її початкова адреса повинна бути кратним 16. Інакше кажучи, ця область повинна бути сегментом пам'яті; вона називається сегментом стека. Початок цього сегмента (перші 16 біт початкової адреси) повинен обов'язково зберігатися в сегментному регістрі SS.

Збережені в стеці елементи можуть мати будь-який розмір, однак треба ураховувати, що в ПК є команди запису в стек і читання з нього тільки слів. Тому для запису байта в стек його треба попередньо розширити до слова, а запис або читання подвійних слів здійснюються парою команд.

У ПК прийнято заповнювати стек знизу нагору, від більших адрес до менших: перший елемент записується в кінець області, відведеної під стек, другий елемент - у попередній осередок області й т.д. Зчитується завжди елемент, записаний у стек останнім. У зв'язку з цим нижня границя стека завжди фіксована, а верхня - змінюється. Слово в пам'яті, у якому перебуває елемент стека, записане останнім, називається вершиною стека. Адреса вершини, відлічена від початку сегмента стека, зобов'язаний перебувати в покажчику стека - регістра SP. Таким чином, абсолютна адреса вершини стека визначається парою SS:SP.

-і-і- -і-і- -і-і-

SS:SP | | SS:SP | | SS:SP | |

| -і-і- запис | -і-і- читання | -і-і-

| | | =======> -і-і>| b | =======> | | |

| -і-і- у стек -і-і- зі стека | -і-і-

-і-і->| a | | a | -і-і>| a |

-і-і- -і-і- -і-і-

Значення 0 у регістрі SP свідчить про те, що стек повністю заповнений (його вершина "дійшла" до початку області стека). Тому для контролю за переповненням стека треба перед новим записом у стек провіряти умову SP=0 (сам ПК цього не робить). Для порожнього стека значення SP повинне рівнятися розміру стека, тобто пари SS:SP повинна вказувати на байт, що випливає за останнім байтом області стека. Контроль за читанням з порожнього стека, якщо треба, зобов'язана робити сама програма.

Початкова установка регістрів SS й SP може бути зроблена в самій програмі, однак в MASM передбачена можливість автоматичного завантаження цих регістрів. Якщо в директиві SEGMENT, що починає опис сегмента стека, указати параметр STACK, тоді асемблер (точніше, завантажник) перед тим, як передати керування на першу команду машинної програми, завантажить у регістри SS й SP потрібні значення. Наприклад, якщо у програмі сегмент стека описаний в такий спосіб:

ST SEGMENT STACK

DB 256 DUP(?) ;розмір стека - 256 байтів

ST ENDS

і якщо під цей сегмент була виділена область пам'яті починаючи з абсолютної адреси 12340h, тоді до початку виконання програми в регістрі SS виявиться величина 1234h, а в регістрі SP - величина 100h (=256). Відзначимо, що ці значення відповідають порожньому стеку.

2. Основні стекові команди

При дотриманні зазначених вимог у програмі можна використати команди, призначені для роботи зі стеком. Основними з них являються наступні.

Запис слова в стек: PUSH op

Тут op позначає будь-який 16-бітовий регістр (у тому числі й сегментний) або адреса слова пам'яті. По цій команді значення регістра SP зменшується на 2 (вирахування відбувається по модулю 2^16), після чого

зазначене операндом слово записується в стек за адресою SS:SP.

Читання слова зі стека: POP op

Слово, лічене з вершини стека, привласнюється операнду op (регістру, у тому числі сегментному, але не CS, або слову пам'яті), після чого значення SP збільшується на 2.

Перехід з поверненням: CALL op

Ця команда записує адресу наступної за нею команди в стек і потім робить перехід за адресою, обумовленому операндом op. Вона використається для переходів на підпрограми із запам'ятовано у стеці адреси повернення.

Є наступні різновиди цієї команди (вони аналогічні варіантам команди безумовного переходу JMP):

- внутрішньо сегментний відносно довгий перехід у цьому випадку в стек заноситься тільки поточне значення лічильника команд IP, тобто зсув наступної команди;

- внутрішньо сегментний абсолютний непрямий перехід (op - адреса слова пам'яті, у якій перебуває адреса (зсув) тієї команди, на яку й буде зроблений перехід) і тут у стек записується тільки зсув адреси повернення;

- між сегментний абсолютний прямий перехід (op - безпосередній операнд виду seg:ofs, а в MASM - це FAR PTR <мітка> або ім'я далекої процедури ) тут у стек заноситься поточне значення регістрів CS й IP (першим у стек записується вміст CS), тобто абсолютна адреса повернення, після чого міняються регістри CS й IP;

- між сегментний абсолютний непрямий перехід (op - адреса подвійного слова, у якому перебуває пара seg:ofs, що задає абсолютну адресу переходу) і тут у стеці рятується вміст регістрів CS й IP.

Перехід (повернення) за адресою зі стека: RET op

Зі стека зчитується адреса й по ньому виробляється перехід. Якщо зазначено операнд (а це повинно бути ненегативне число), то після читання адреса стек ще очищається на це число байтів (до SP додається це число). Команда використається для повернення з підпрограми за адресою, записаною в стек по команді CALL при виклику підпрограми, і одночасного очищення стека від параметрів, які основна програма занесла у стек перед звертанням до підпрограми.

Команда RET має два різновиди (хоча в MASM вони записуються однаково): в одному випадку зі стека зчитується тільки одне слово - зсув адреси повернення, а в другому - зі стека зчитується пара seg:ofs, що вказує абсолютну адресу повернення.

У ПК стек в основному використовується для організації підпрограм й переривань.

Навіть якщо програмі не потрібний стек, вона однаково повинна відвести під нього місце. Справа в тому, що стеком буде неявно користуватися операційна система при обробці переривань, які виникають (наприклад, при натисканні клавіш на клавіатурі) у той час, коли виконується програма. Для потреб ОС рекомендується виділяти в стеці 64 байта.

Лекція 9

Тема: Процедури

1. Організація процедур та переривань

2. Передача параметрів процедурам через регістри, через стек, через таблиці, через глобальні області

3. Процедури в асемблері

1. Організація процедур та переривань

Процедурою в асемблері є те що в інших мовах програмування називають підпрограмами, функціями процедурами і т.д. Асемблер не накладає на процедури ні яких обмежень, на будь-яку адресу програми можна передати управління командою CALL, і подальше виконання програми передасться вказаної процедури. Виконання тієї чи іншої процедури буде продовжуватись до першого входження команди RET. Така свобода вираження команд може легко призвести до важко читаних програм. У зв'язку з цим у асемблер були включені директиви логічного оформлення процедур.

Мітка proc мова тип USES регістри ;TASM. Або

Мітка proc тип мова USES регістри ;MASM/WASM ret

Мітка endp

Всі операнди PROC необов'язкові.

Тип може приймати значення NEAR та FAR, і якщо він вказаний всі команди RET в тілі процедури будуть замінені відповідно RETN та RETF. По замовчуванню розуміють, що процедура має тип NEAR в моделях пам'яті TINY, SMALL, COMPACT.

PROC дозволяє рахувати параметри, які передаються викликаючого програмою. В цьому випадку необхідно вказати мову високого рівня, так як різні мови високого рівня використовують різні способи передачі параметрів.

USES - список регістрів, значення яких змінює процедура. Асемблер розміщує на початок процедури набір команд PUSH, а перед командою RET - набір команд POP, так що значення перерахованих регістрів будуть відновлені.

2. Передача параметрів процедурам через регістри, через стек, через таблиці, через глобальні області

Процедури можуть отримувати і не отримувати параметри із визваної процедури і можуть повертати або не повертати відповіді.

На мові асемблера параметри для процедур можна передавати за допомогою шести способів:

По значенню

По сильці

По повернутому значенню

По результату

По імені

Ускладненим розрахуванням

Параметри можна передавати в одному із п'яти місць:

В регістрах

В глобальних перемінних

В стеку

У потоці коду

В блоку параметрів

Розглянемо деякі способи передачі параметрів для процедур

Передача параметрів по значенню

Процедурі передається значення параметру. При цьому значення параметру фактично копіюється, і процедура використовує його копію, так що модифікація вихідного параметру неможлива. Цей механізм використовується для передачі таких параметрів як байти або слова.

Приклад: (параметри передаються в регістрах)

Mov ax, word ptr value ; Сделать копию значения

Call procedure ; Вызвать процедуру

3. Передача параметрів по ссылке

Процедурі передається не значення змінної, а її адреса, по якої процедура сама прочитає значення параметру. Такий механізм зручний для передачі великих масивів даних, і в тих випадках коли процедура повинна модифікувати параметри.

Приклад:

Mov ax, offset value

Call procedure

4. Передача параметрів по повернутому значенню

Цей механізм з'єднує передачу по значенню та передачу по ссылке. Процедурі передають адресу змінної, а процедура робить локальну копію параметру і потім працює з нею.

Приклад:

Mov global_variable, offset value

Call procedure

[…….]

procedure proc near

mov dx, global_variable

mov ax, word ptr [dx]

mov word ptr [dx], ax

procedure endp

5. Передача параметрів в стеку

Спочатку параметри заносяться в стек перед виловом процедури. Саме цей метод використовують мови високого рівня, такі як C, Pascal. Для читання параметрів із стеку використовують не команду POP, а регістр BP, в який заносять адресу вершини стеку після входу в процедуру.

Приклад:

Push parameter1 ; поместить параметр в стек

Push parameter2

Call procedure

Add sp,4 ; освободить стек

[……]

procedure proc near

push bp

mov bp, sp

(команди, які можуть використовувати стек)

mov ax, [bp+4] ; считать параметр 2

mov bx, [bp+6]

pop bp

ret

procedure endp

6. Локальні змінні

Дуже часто процедурам потрібні змінні які потім не будуть використовуватись в головної програмі. Такі змінні прийнято називати локальними. Існує декілька способів зберігання локальних змінних. Найбільш розповсюджений спосіб зберігати локальні перемінні в стеку.

Приклад:

Fob proc near

Fob_x equ [bp+8]

Fob_y equ [bp+6]

Fob_z equ [bp+4]

Fob_l equ [bp-2]

Fob_m equ [bp-4]

Fob_n equ [bp-6]

Push bp

Mov bp, sp

Sub sp,6

Mov ps, bp

Pop bp

Ret 6 ;Повернутися видаливши параметри із стека

Fob endp.

Лекція 10

Тема: Процеси і потоки

1. Процеси і потоки

Процес - завантажена на згадку й готова до виконання програма. Кожен процес має свій власний віртуальний адресний простір (4Gb). Процес складається з коду, даних й інших системних ресурсів, таких як відкриті файли, канали (pipes), що синхронізують об'єкти.

Потік(thread) - базовий об'єкт, якому операційна система розподіляє час центрального процесора. Виконання процесу починається зі стартового потоку. Надалі він може породжувати інші потоки. Ресурси процесу доступні всім його потокам. Кожен потік використає структуру даних, для збереження контексту виконання, у той час, коли в нього віднімається процесор. У контекст входять регістри процесора, змінні оточення, стеки ядра й користувача. Всі потоки одного процесу спільно використають його віртуальний адресний простір. Процесорний час розподіляється по черзі між потоками, а не між процесами. Тривалість кванта виділення часу становить близько 20 мс.

1.1 Розподіл часу між потоками

Процесорний час виділяється потокам відповідно до їх рівня пріоритету. Потоку з більше низьким пріоритетом не виділяється час, якщо на нього претендує потік з більше високим рівнем пріоритету. Більше того, процес із більше низьким пріоритетом переривається до витікання кванта часу, якщо на процесор претендує потік з більше високим рівнем пріоритету. Необхідно пам'ятати, що в середовищі Windows основна «робота» потоку складається чекаючи події й реагуванні на нього. Це дає шанс на виконання потокам з низьким рівнем пріоритету.

Рівні пріоритетів варіюються в діапазоні від 0 (нижчий) до 31 (вищий).

Рівень пріоритету кожного потоку складається із трьох складових

клас пріоритету процесу (простоюючий , нормального, високий, реального часу)

рівень пріоритету потоку усередині класу пріоритету процесу (нижній, нижче нормального, нормальний, вище нормального, вищий)

динамічно встановлений рівень пріоритету.

Клас пріоритету процесу

Таблиця 1.1

Клас

Прапор у функції CreateProcess

Числовий рівень

Idle (простоюючий)

IDLE PRIORITY CLASS

4

Normal (нормальний)

NORMAL PRIORITY CLASS

7-9

High(високий)

HIGH PRIORITY CLASS

13

Real time(peanbHoro часу)

REALTIME_PRIORITY_CLASS

24

При запуску на виконання процесу йому призначається один із чотирьох класів пріоритету. Рівень Idle призначається процесу, що нічого не повинен робити у випадку активності інших процесів (наприклад, хоронитель екрана). Процесам, що запускає користувачем, привласнюється нормальний рівень. Користувач може запустити кілька процесів. Тому процесу, з яким користувач безпосередньо працює (а це може бути тільки один процес) рівень пріоритету піднімається на дві одиниці (7+2 - 9). Це робить спілкування із прикладною програмою більше «комфортабельним». Високий клас пріоритету призначається деяким системним процесам, які простоюють до виникнення певних подій й, тому, не заважають іншим процесам. Тільки в особливих випадках процес може ставитися до класу Real time.

1.2 Динамічна зміна рівня пріоритету потоку

Клас пріоритету процесу й рівень пріоритету потоку усередині класу визначають базовий рівень пріоритету потоку. Цей рівень може динамічно змінюватися системою, а саме, підвищуватися на 2 одиниці у відповідь на надходження повідомлень у чергу потоку з наступним зниженням до базового рівня після закінчення певного проміжку часу. Це правило діє тільки для потоків до 15 рівня.

2. Робота із процесами й потоками в Win32 API

Таблиця 1.2 Рівень пріоритету потоку усередині класу пріоритетів

Ідентифікатор

Рівень пріоритету потоку

THREAD_PRfORlTYJJDWEST

На 2 нижче рівні класу

THREAD PRIORITY BELOW NORM Ha 1 нижче рівня класу

AL

THREAD_PRIORITY_NORMAL

THREAD PRIORITY ABOVE NORMA Ha 1 вище рівня класу L

THREAD_PRIORITY_HIGHEST

На 2 вище рівні класу

THREAD_PRIORITY_IDLE

Дорівнює 1 для процесів класу

IDLE PRIORITY CLASS,

NORMAL PRIORITY CLASS, і

HIGH PRIORITY CLASS і дорівнює 16

для REALTIME PRIORITY CLASS

THREAD_PRI0R1TY_TIME_CRITICAL Дорівнює 15 для процесів класу

IDLE PRIORITY CLASS,

NORMAL PRIORITY CLASS, і

HIGH_PRIORITY_CLASS, і дорівнює

31 для

REALTIME PRIORITY CLASS

Динамічна зміна рівня пріоритету потоку. Клас пріоритету процесу й рівень пріоритету потоку усередині класу визначають базовий рівень пріоритету потоку. Цей рівень може динамічно змінюватися системою, а саме, підвищуватися на 2 одиниці у відповідь на надходження повідомлень у чергу потоку з наступним зниженням до базового рівня після закінчення певного проміжку часу. Це правило діє тільки для потоків до 15 рівня.

Функція CreateProcess()

Формат функції:

CreateProcess(

LPCTSTR IpApplicationName,// ім'я файлу, що виконує

LPTSTR IpCommandLine, II командний рядок

LPSECURITY_ATTRIBUTES IpProcessAttributes, //атрибути захисту процесса

LPSECURITY_ATTRIBUTES IpThreadAttributes, II атрибути захисту потоку

BOOL blnheritHandles, II прапор спадкування описателей

DWORD dwCreationFlags, II прапори створення

LPVOID IpEnvironment, II покажчик блоку змінні середовища

LPCTSTR IpCurrentDirectory, II поточний каталог

LPSTARTUPINFO IpStartuplnfoJJ блок початкових параметрів LPPROCESSJNFORMATION IpProcessInformation II покажчик структури, що описує породжений процес

);

Параметри:

IpApplicationName - покажчик на рядок, що містить ім'я виконує программы, що. Ім'я може бути повне. Якщо воно не повне, то пошук файлу виробляється в поточному каталозі. Параметру може бути привласнене значення NULL. У цьому випадку як ім'я файлу виступає перша відокремлена пробілами лексема з рядка IpCommandLine;

IpCommandLine - покажчик командного рядка. Якщо параметр IpApplicationName має значення NULL, то ім'я файлу, що виконує, виділяється з IpCommandLine, а пошук файлу, що виконує, виробляється відповідно до правил, що діють у системі;

IpProcessAttributes - покажчик на структуру, що описує параметри захисту процесу. Якщо параметру привласнене значення NULL, то встановлюються атрибути «за замовчуванням»;

lp ThreadAttributes- покажчик на структуру, що описує параметри захисту первинного потоку. Якщо параметру привласнене значення NULL, то встановлюються атрибути «за замовчуванням»;

blnheritHandles - визначає, чи буде породжений процес успадковувати описатели (handles) об'єктів батьківського процесу. Наприклад, якщо батьківський процес А вже до цього породжував процес В, те він одержав описатель процесу В и може ним маніпулювати. Якщо тепер він породжує процес С с параметром blnheritHandles рівним TRUE, то й процес Зі зможе працювати з описателем процесу В;

dwCreationFlags - визначає деякі додаткові умови створення процесу і його клас пріоритету;

IpEnvironment- покажчик на блок змінні середовища породженого процесу. Якщо цей параметр дорівнює NULL, то породжений процес успадковує середовище батька. Інакше він повинен указувати на блок рядків, що завершується нулем, кожна з яких завершується нулем (аналогічно DOS);

IpCurrentDirectory - покажчик на рядок, що містить повне ім'я поточного каталогу породженого процесу. Якщо цей параметр дорівнює NULL, то породжений процес успадковує каталог батька;

IpStartuplnfo - покажчик на структуру STARTUPINFO, що визначає параметри головного вікна породженого процесу;

IpProcesslnformation - покажчик на структуру, що буде заповнена інформацією про породжений процес після повернення з функції.

Приклад: програма, що запускає Microsoft Word

#include <windows.h> #)nclude <conio.h> «include <stdio.h> main()

{ PROCESSJNFORMATION pi; STARTUPINFO si ;

ZeroMemory( &si, sizeof(si)); si.cb = slzeof (si);

printf( "Press any key to start WinWord - "); getch();

CreateProcess( MULL, "WinWord", NULL, NULL, FALSE, 0,

NULL, NULL, &si, &pi); return 0;

}

Лекція 11

Тема: Архітектура пам'яті в Win32 API

1. Адресний простір процесу

В Win32® API використається пласка ' 32-розрядна модель пам'яті. Кожному процесу виділяється «особисте» (private) ізольований адресний простір, розмір якого становить 4Gb. Цей простір розбивається на регіони, небагато відмінні для Windows'95 й Windows NT. У загальному для тієї й іншої системи можна сказати, що нижні 2Gb ці простори відведені процесу для вільного використання, а верхні 2Gb зарезервовані для використання операційною системою.

Програма, лістинг якої наведений нижче, намагається обнулити сторінку за сторінкою в системній області (старший гігабайт адресного простору). Операція може завершитися невдачею по двох причинах. По-перше, реальної сторінки по зазначеній адресі може не бути1, а, по-друге, якщо сторінка існує, то може бути заборонений у неї доступ. Програма намагається обнулити сторінку (try) і, якщо одержує відмову (catch), те друкує про це повідомлення й переходить до наступної сторінки.

#include <windows.h> #include <iostream h>

void main()

{ II Системна область. Старший Gb адресного простору DWORD System Area Address = OxCOOOOOOO ;

while(1){

try {II Спроба запису

ZeroMemory( (LPVOID) System Area Address, 0x1000 );

}

catch(...) {II помилка запису

cout« "Exception: " « hex « SystemAreaAddress « endl;

}

SystemAreaAddress += 0x1000 ; II Перехід до наступної сторінки (4ДО)

}

Оскільки в Windows'95 відсутня захист сторінок системної області, то програма знищує цю область, що приводить до краху системи. Windows NT захищає системну область й, тому, «витримує натиск» програми.

2. Керування віртуальною пам'яттю. VMM

VMM(Virtual Memory Manager) - частина операційної системи, що займається керуванням віртуальною пам'яттю. В Win32 використається сторінкова організація пам'яті. Розмір сторінок для платформ Intel й MIPS становить 4ДО. Розмір сторінок для DEC Alpha становить 8ДО.

Схема сторінкового перетворення в процесорах Intel докладно вивчалася в курсі «Програмування мовою асемблера. Частина 3». Win32 використає двоступінчасту схему сторінкового перетворення, підтримувану процесорами 386,486, Pentium. Додаткові схеми, які підтримує процесор Pentium Pro, не використаються.

Рис 10.1 - Керування віртуальною пам'яттю. VMM.

Кожному процесу призначається свій каталог сторінок. Саме тому адресний простір кожного процесу ізольовано.

Організацією свопинга займається VMM. При генерації системи на диску утвориться спеціальний файл свопинга, куди записуються ті сторінки, яким не перебуває місця у фізичній пам'яті. Процеси можуть захоплювати пам'ять у своєму 32-бітному адресному просторі й, потім, використати неї. При обігу потоку до комірки пам'яті можуть виникнути три різні ситуації:

Сторінка існує й перебуває в пам'яті

Сторінка існує й вивантажена на диск

Сторінка не існує

3. Файли даних, що проектуються на згадку

Проектування файлу даних в адресний простір процесу надає потужний механізм роботи з файлами. Зпроектувати файл на адресний простір процесу, програма одержує можливість працювати їм, як з масивом. Проектування файлу на згадку виконується в три етапи

Створюється об'єкт ядра «файл». У колишній термінології це операція відкриття файлу. Для створення об'єкта «файл» використається функція CreateFile, аналогічна функції ореп() з CRT-бібліотеки.

За допомогою функції CreateFileMapping створюється об'єкт ядра «проецируемый файл». При цьому використається описатель файлу (handle), повернутий функцією CreateFile. Тепер файл готовий до проектування.

Виробляється відображення об'єкта «проецируемый файл» або його частини на адресний простір процесу. Для цього застосовується функція MapViewOfFile.

Для відкріплення файлу від адресного простору процесу використається функція UnmapViewOfFile, а для знищення об'єктів «файл» й «проецируемый файл» - функція CloseHandle.

Загальна схема роботи із проецированными файлами така:

HANDLE hFile, hFileMapping; PVOID pMassive;

hFile = CreateFHe( «File Name»,...); hFileMapping = CreateFileMapping( hFile,...); CloseHandlef hFile); pMassive = MapViewOfFile( hFileMapping,...);

t* Робота з масивом pMassive */

UnmapViewOfFile( pMassive);

4. Взаємодія процесів через загальну область даних. Когерентність

Два процеси можуть спільно використати об'єкт «проектований файл». При цьому, за допомогою функції MapViewOfFile кожен процес проектує цей об'єкт на свій адресний простір і використають цю частину адресного простору як поділювану область даних. Загальний механізм такий: один процес створює об'єкт «проектований файл» за допомогою функції CreateFileMapping і породжує інший процес, передаючи йому в спадщину описувачем цього об'єкта. Дочірній процес може користуватися цим описувачем нарівні з батьківським. Проблема складається тільки в тім, як повідомити дочірньому процесу, який з переданих йому в спадщину описувачів є описувачем «проецируемого файлу». Це можна зробити будь-яким способом. Наприклад передачею параметрів при запуску процесу, через змінні середовища, передачею повідомлення в головне вікно процесу й так далі.

Загальна область даних може бути створена не тільки шляхом проектування файлу, але й шляхом проектування частини файлу підкачування. Для цього у функцію CreateFileMapping необхідно передати як параметр не описувач раніше відкритого файлу, а -1. У цьому випадку необхідно задати розміри виділюваної області. Крім того, у параметрі IpName можна задати ім'я об'єкта, що є глобальним у системі. Якщо це ім'я задається в системі вперше, то процесу виділяється нова область даних, а якщо ім'я було вже задане, те іменована область даних надається для спільного використання.

Рис 10.2 - Взаємодія процесів через загальну область даних. Когерентність.

Якщо один процес міняє поділювану область даних, то вона міняється й для іншого процесу. Операційна система забезпечує когерентність поділюваної області даних для всіх процесів. Але для забезпечення когерентності процеси повинні працювати з одним об'єктом «проектований файл», а не з одним файлом.

5. Купи

Купи (heaps) - області, що розподіляють динамічно, даних. При породженні процесу йому надається купа «за замовчуванням», розміром 1Mb. Розмір цієї купи може змінюватися параметром /HEAP при побудові модуля, що виконує. CRT - функції (malloc. free і т.д.) використають функціональність куп (див. 4.3)

Для одержання описувача купи «за замовчуванням» використається функція

HANDLE GetProcessHeap( VOID )

Використовуючи поверта цією функцією описатель (handle) можна здійснювати роботу з купою. Для цього призначені функції:

LPVOID HeapAlloc( HANDLE hHeap, DWORD dwFlags, DWORD dwSize )

виділяє блок пам'яті заданого розміру з купи й повертає покажчик на цей блок;

LPVOID HeapReAlloc( HANDLE hHeap, DWORD dwFlags, LPVOID IpOldBlock, DWORD dwSize)

змінює розмір виділеного блоку пам'яті. При цьому вона може переміщати блок, якщо в купі немає місця для простого розширення.

BOOL HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID IpMem )

звільняє виділений блок пам'яті з купи.

Існує ще ряд функція роботи з купами, повний опис яких утримується в документації.

Іноді має сенс користуватися додатковими купами. Для їхнього створення використається функція

HANDLE HeapCreate(DWORD dwFlags, DWORD dwInitialSize, DWORD dwMaximumSize )

Причин доцільності використання додаткових куп може бути трохи:

1. Для захисту друг від друга різних структур даних.

Рис 10.3 - Структури.

2. Для підвищення ефективності керування пам'яттю.

У системах зі сторінковою організацією відсутня проблема фрагментації фізичної пам'яті1. Однак існує проблема фрагментації адресного простору. В 4Gb адресному просторі ця проблема не актуальна, але вона має значення в 1Mb купі. Якщо елементи якої-небудь структури мають один розмір, а елементи іншої структури - інший розмір, то корисно розміщати ці структури в різних купах.

3. Для зменшення робочої безлічі процесу.

Відповідно до принципу локальності, робота з різними структурами, найчастіше, відбувається не одночасно. Границі елементів різних структур не вирівняні на границю сторінки. Звертання до елементів однієї структури викликає підкачування всієї сторінки, а, значить й елементів іншої структури. Це збільшує робочу безліч процесу.

Рис 10.4 - Кучі.

Лекція 12

Тема: Вікна

1. Визначення вікна. Компоненти й параметри вікон

Вікно - це прямокутна частина екрана, у якій додаток робить відображення виведеної інформації.

У кожен момент часу тільки одне вікно в системі може одержувати вступну інформацію. Користувач може використати клавіатуру, мишу або інше пристрою уведення для взаємодії з вікном.

Коли Windows завантажується, створюється вікно, яке займає весь екран (desktop window). Кожен windows-додаток створює хоча б одне вікно, називане головним вікном додатка. Багато додатків створюють ще додаткові вікна. Вікно додатка може складатися з наступних компонентів:

Рис 12.1 - Структура вікна

Додатка можуть використати й інші типи вікон:

елементи керування (controls)

вікна діалогу (dialog boxes)

вікна повідомлень (message boxes)

Для породження вікна (у тому числі й головному вікні додатка) використається функція CreateWindowEx . Додаток для створення вікна повинне визначити наступні параметри:

Клас вікна (Window class)

Ім'я вікна (Window name)

Стиль вікна (Window style)

Батьківське вікно або вікно-хазяїн (Parent or owner window)

Розміри (Size)

Координати лівого верхнього кута (Location)

Місце в порядку розташування (Position in the Z-order)

Ідентифікатор дочірнього вікна або описатель меню (Child-window identifier or menu handle)

Описувач екземпляра програми (Instance handle)

Додаткові дані (Creation data)

2. Клас вікна

Кожне вікно в системі належить до якому або класу. Вікна одного класу працюють «однаково». Це пов'язане з тим, що клас вікна визначає, по-перше, ряд зовнішніх атрибутів (форму курсору, параметри тла, ікону), а, по-друге, всі вікна одного класу працюють із однієї й тією же функцією вікна.

Існує три типи класів вікна:

Системні глобальні класи: класи, які реєструються при завантаженні операційної системи. До таких класів ставляться класи елементів керування (кнопки, списки, смуги прокручування й т.д.)

Прикладні глобальні класи: класи, які реєструються бібліотеками, що зв'язують динамічно (DLL) і доступні всім додаткам системи

Прикладні локальні класи: класи, які додатка реєструють для свого внутрішнього використання.

Для реєстрації класів використається функція RegsterClass (RegisterClassEx).

3. Ієрархія вікон

Windows управляє кожним вікном залежно від відносин цього вікна з іншими вікнами системи. Інформація про взаємини вікон зберігається в списку диспетчера вікон (window manager's list). Кожне вікно в цьому списку визначається спеціальною структурою, усередині якої нам цікаві чотири поля:

Рис 12.2 - Спеціальна структура вікна

Описатель батьківського вікна

Описатель вікна - хазяїна

Описатель дочірнього вікна

Описатель наступного вікна в списку братів При завантаженні Windows створює вікно

робочого стола (Desktop window). Це вікно займає весь екран. Це вікно завжди лежить на початку списку диспетчера вікон. Наступний рівень ієрархії становлять вікна верхнього рівня (top-level windows). До таких вікон ставляться всі не дочірні вікна. Вікна верхнього рівня з'єднуються з вікном робітника стола в такий спосіб:

кожне вікно посилається на вікно робочого стола як на батьківське

вікно робочого стола посилається на саме верхнє вікно з вікон верхнього рівня

всі вікна верхнього рівня, крім самого нижнього, посилаються один на одного, образуя односпрямований зв'язний список братів. Порядок розташування вікон у цьому списку визначає черговість перекриття вікон.

Рис 12.3 - Спеціальна структура вікна

Вікна верхнього рівня можуть так само вступити у відносини володіння. Якщо при породженні вікна вказати як вікно власника вікно не верхнього рівня, то система здійметься по ланцюжку батьківських вікон і призначить як хазяїн відповідне вікно верхнього рівня. Вікно діалогу завжди належить його вікну, що породило, за винятком тих випадків, коли воно породжується як дочірнє.

Рис 12.4 - Спеціальна структура вікна

Будь-які вікна можуть мати дочірні вікна. При цьому кожне вікно містить покажчик на початок списку дочірніх вікон. У системі можуть утворюватися досить складні й розгалужені структури

Лекція 13

Тема: Взаємодія процесів. Обмін даними між процесами. Синхронізація потоків

1. Обмін даними між процесами

При розробці додатка в середовищі Win32 необхідно задатися питанням, необхідно чи передбачити можливість обміну даними цього додатка з іншими додатками і якими додатковими умовами накладають на спосіб цього обміну.

Чи буде додаток спілкуватися з іншими тільки на локальному комп'ютері або необхідно передбачити взаємодію в мережі?


Подобные документы

  • Внутрішнє представлення в пам’яті комп’ютера даних базових та похідних типів, масивів. Ідентифікатор, зв'язаний з константним виразом та основи представлення даних. Алгоритм представлення цілих, дійсних, логічних і символьних чисел, структур і об’єднань.

    курсовая работа [279,1 K], добавлен 25.08.2014

  • Класифікація програмного забезпечення, системне та прикладне забезпечення, інструментальні системи. Програмна складова комп'ютерної системи, опис алгоритмів розв'язання певної задачі. Класифікація операційних систем, основні групи прикладних програм.

    презентация [945,0 K], добавлен 01.04.2013

  • Операція алгебраїчного додавання, множення, ділення. Алгоритм ділення модулів чисел. Поняття граф-схеми алгоритму та правила її складання. Основні поняття теорії цифрових автоматів. Синтез керуючого автомата. Контроль виконання арифметичних операцій.

    реферат [55,4 K], добавлен 24.03.2009

  • Склад сучасного настільного персонального комп'ютера. Системне та прикладне програмне забезпечення. Взаємодія користувача з операційною системою MS DOS. Програмна оболонка Norton Commander. Операційна система Microsoft Windows. Основні поняття та команди.

    курсовая работа [1,3 M], добавлен 18.05.2013

  • У наш час Windows ХР є найбільш сучасною настольною операційною системою. Windows ХР, яка займає серед настольних комп’ютерів долю у 84,56 % вимагає досить потужного комп’ютера. Порівняння інтерфейсу операційних систем Windows 98 та Windows ХР.

    реферат [4,4 M], добавлен 24.06.2008

  • Економічна інформація, її види та властивості. Апаратне і програмне забезпечення ПК. Програмне забезпечення стаціонарних комп’ютерів. Комп’ютерні мережі, загальна характеристика глобальної мережі Інтернет. Напрямки використання комп’ютерної техніки.

    контрольная работа [28,0 K], добавлен 06.10.2011

  • Подання чисел у нормальній формі. Порядок нормалізації чисел з рухомою комою. Правила додавання двійкових чисел з рухомою комою. Алгоритми і програми додавання чисел в арифметиці з рухомою комою в інструкціях навчального комп'ютера-симулятора DeComp.

    лабораторная работа [31,7 K], добавлен 13.03.2011

  • Програмне забезпечення ПК, їх структура, склад пристроїв ПК. Об’єкти, які створюються в СУБД Microsoft Access. Їх призначення та застосування. Типи серверів за функціями, які вони підтримують. Системи адресації в Internet. Принципи побудови адрес.

    реферат [18,6 K], добавлен 29.05.2008

  • Web-браузери як програмне забезпечення для комп'ютера або іншого електронного пристрою. Загальна характеристика мови програмування Delphi, розгляд функцій. Аналіз етапів розробки браузера на основі Internet Explorer, знайомство з основаними особливостями.

    дипломная работа [2,1 M], добавлен 06.12.2013

  • Режими роботи з таблицями в Microsoft Access. Основні способи створення таблиць. Вимоги до технічних характеристик комп'ютера. Створення бази даних. Техніка безпеки та основні правила при виконанні робіт на комп'ютері. Порядок архівування роботи.

    реферат [1,5 M], добавлен 23.12.2010

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.