Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Kursovoy Юрков.doc
Скачиваний:
1
Добавлен:
18.09.2019
Размер:
339.97 Кб
Скачать

2) Практична частина

18. Дані цілі числа a1, …, an (в послідовності можуть бути члени, що повторюються). Знайти кількість чисел, що входять у послідовність більше ніж по одному разу.

2. Опис алгоритму:

1) Якщо і більше ніж довжина поданого масиву, то переходимо до 6, інакше запам’ятовуємо і-е число в заданому масиві.

2) Порівнюємо запам’ятоване число з числами у масиві, що стоять після цього числа.

3) Якщо дані два числа рівні, то порівнюємо запам’ятоване число з кожним елементом другого масиву чисел, що складається з елементів, які повторюються у заданому масиві більше ніж один раз.

4) Якщо є співпадання, то збільшуємо і на один, та переходимо до кроку 1

5) Якщо співпадання не було, то зберігаємо запам’ятоване число у другому масиві. Переходимо до кроку 1.

6) Вивід кількості єлементів у другому масиві та завершуємо роботу програми.

Блок-схема: альтернативный процесс 1 Прямая соединительная линия 2 Блок-схема: данные 3

Прямая соединительная линия 4 Прямая со стрелкой 33 Прямая соединительная линия 34 Прямая соединительная линия 50 Прямая со стрелкой 52

Блок-схема: решение 6

Прямая соединительная линия 8 Прямая соединительная линия 9 ні

Прямая соединительная линия 7

Прямая со стрелкой 28 Блок-схема: решение 30 Прямая соединительная линия 35 так

ні

Прямая соединительная линия 32

i = i + 1

Прямая соединительная линия 38

j = i + 1

ah = mas1[i]

Прямая соединительная линия 18 Прямая соединительная линия 31 Прямая соединительная линия 39 Прямая соединительная линия 40 так

Блок-схема: решение 19 Прямая соединительная линия 22

Прямая соединительная линия 21 ні

Блок-схема: решение 41 Прямая соединительная линия 42 Прямая со стрелкой 44

countMas2 = 1

Mas2[0] = ah

так

Прямая со стрелкой 53 Прямая со стрелкой 59 так

cx = countMas2

Прямая со стрелкой 55

нПрямая со стрелкой 46 Прямая соединительная линия 58

k = cx – 1

Прямая со стрелкой 64 Прямая соединительная линия 66 і

Прямая со стрелкой 60 Прямая соединительная линия 74 Прямая со стрелкой 75

i = i + 1

Прямая соединительная линия 48 Блок-схема: решение 56 так

Прямая соединительная линия 10 Прямая соединительная линия 11 Блок-схема: данные 12 Блок-схема: альтернативный процесс 14 Прямая соединительная линия 49 Прямая соединительная линия 57 Прямая соединительная линия 65 Блок-схема: решение 67 Прямая соединительная линия 68 Прямая соединительная линия 72 Прямая со стрелкой 73 ні

ні

так

3. Код програми

assume CS:code, DS:Data

code segment

begin: mov ax,data

mov ds,ax

xor cx,cx

mov si,0

mov di,0

mov bp,0

b1: mov bx,si

add bx,1

mov di,si

cmp bx,countMas1

jae exit ;если i указывает на последний элемент mas1, либо больше, то выходим

b2: mov bx,di

add bx,1

cmp bx,countMas1

jae addI

b3: add di,1

mov ah,mas1[si]

b4: cmp ah,mas1[di]

jne b2

b5: mov al,0

cmp BYTE PTR [countMas2],al

jne b7

b6: mov countMas2,1

mov mas2[0],ah

jmp addI

b7: mov cx,countMas2

b8: mov bp,cx

sub bp,1

b9: cmp ah,mas2[bp]

je addI

b9s: mov al, 1

cmp cl, al

jne b10

b9ss: mov bp,countMas2

mov mas2[bp],ah

add countMas2,1

jmp addI

b10: loop b8

addI: add si,1

jmp b1

exit: mov ax,countMas2

aam

add ax,3030h

mov dl,ah

mov dh,al

mov ah,02

int 21h

mov dl,dh

int 21h

mov ah,09h

mov dx,offset msg

int 21h

mov ah,4ch

int 21h

code ends

data segment

msg db ' numbers that repeat more that 1 times $'

mas1 db 6, 200, 1, 8, 9, 20, 20, 9, 1, 8

db -1, -3, -1, -114, 18, 9, 12, 6, 200

mas2 db 20 dup (?)

;i db 0 si

;j db 0 di

;k db 0 bp

countMas1 dw 20

countMas2 dw 0

data ends

stk segment stack

db 256 dup()

stk ends

end begin

3-я частина

Операційна система Windows. Системне програмування в masm32 з використанням функцій api.

  1. Теоретична частина

  1. Використання Win32 API

  2. Особливості здійснення та передачі повідомлень в Win32 API

  1. Практична частина

  1. Завдання

  2. Опис алгоритму

  3. Код програми

1)Теоретична частина

1. Використання Win32 API Windows надає величезну кількість ресурсів Windows-програм через Windows API (Application Programming Interface). Windows API - це велика колекція дуже корисних функцій, що розташовуються безпосередньо в операційній системі і готових для використання програмами. Ці функції знаходяться в декількох динамічно загружених бібліотек, таких як kernel32.dll, user32.dll, gdi32.dll і т.д. Kernel32.dll містить API функції, взаємодіють з пам'яттю і керуючі процесами. User32.dll контролює користувальницький інтерфейс. Gdi32.dll відповідальний за графічні операції. Крім цих трьох "основних", існують також інші динамічні бібліотеки, які можна використовувати за умови, що володієте достатньою кількістю інформації про потрібні API функціях. Windows-програми динамічно під'єднуються до цих бібліотек, тобто код API функцій не включається в виконуваний файл. Інформація знаходиться в бібліотеках імпорту. Потрібно з’єднати програми з правильними бібліотеками імпорту, інакше вони не зможуть знайти ці функції. Коли Windows-програма завантажується в пам'ять, Windows читає інформацію, збережену в програмі. Ця інформація включає імена функцій, які програма використовує і DLL-бібліотек, в яких ці функції розташовуються. Коли Windows знаходить подібну інформацію в програмі, вона викликає бібліотеки і виправляє в програмі виклики цих функцій, так що контроль завжди буде передаватися за правильною адресою. Існує дві категорії API функцій: одна для ANSI й інша для Unicode. На кінці імен API функцій для ANSI стоїть "A", наприклад, MessageBoxA. Наприкінці імен функцій для Unicode знаходиться "W". Ми звичайно маємо справу з ANSI рядками (масиви символів, що закінчуються NULL-ом). Розмір ANSI-символу - 1 байт. У той час як ANSI достатня для європейських мов, вона не підтримує деякі східні мови, в яких є кілька тисяч унікальних символів. Ось у цих випадках в справу вступає Unicode. Розмір символу UNICODE - 2 байта, і тому може підтримувати 65536 унікальних символів. Але здебільшого, використовуються include-файли, які можуть визначити і вибрати підходящу для платформи функцію. Тоді досить звертатися до імен API функцій без постфікса.

2. Особливості здійснення та передачі повідомлень в Win32 API

В Win32 в зв'язку з появою багато потокових додатків змінився процес маршрутизації повідомлень в системі. Тепер черга повідомлень належить не додатку (процесу), а потоку, що створив її. Потік, що не використовує черг і, відповідно, не має циклу обробки повідомлень, називається робочим потоком (worker thread), а потік, який працює з вікнами, що створює свою чергу і цикл обробки повідомлень називається інтерфейсним потоком (interface thread). В одному додатку Win32 може виявитися кілька робочих потоків, кілька інтерфейсних потоків і, відповідно, кілька черг одночасно. Ще одна відмінність пов'язана з тим, що розмір черги більше не фіксований - при необхідності чергу динамічно збільшують. Завдяки цьому функція SetMessageQueue більше не застосовується. Можливість застосування декількох інтерфейсних потоків в одному процесі призводить додатково до відмови від функції PostAppMessage - так як залишається неясно, якому потоку треба послати повідомлення, і до додавання функції: BOOL PostThreadMessage (dwThreadID, uMsg, wParam, lParam); яка посилає повідомлення конкретному потоку. При цьому в чергу відповідного потоку поміщається повідомлення, що має нульовий «хендл» вікна-одержувача. Ідентифікатор потоку dwThreadID можна отримати за допомогою функцій: DWORD GetWindowThreadProcessId (hWnd, lpdwProcessID); DWORD GetCurrentThreadId (void); Так як один процес може мати кілька потоків, кожен зі своєю чергою і своїми вікнами, та повідомлення можуть передаватися (SendMessage) вікнам будь-якого потоку і навіть будь-якого процесу, то для забезпечення необхідного рівня захисту було прийнято рішення, що б повідомлення, спрямовані вікну, оброблялися тільки тим потоком, який це вікно створив. Якщо повідомлення передається вікну, створеному тим-же потоком, то функція SendMessage просто викликає віконну процедуру для обробки повідомлення. А якщо вікно створене іншим потоком, то процес передачі повідомлення призводить до складного взаємодії потоку-відправника і потоку-одержувача. Передавальний потік поміщає повідомлення в чергу приймає потоку зі спеціальним прапором передане повідомлення (QS_SENDMESSAGE) і припиняється до одержання відповіді. Приймаючий потік, закінчивши обробку поточного повідомлення, витягує з черги першими повідомлення з прапором передане, обробляє їх, повертає результат і після цього відновлює роботу потоку, який передав повідомлення. Проте в житті ситуація суттєво ускладнюється: часто потік, що обробляє передане повідомлення, передає потоку, передав повідомлення, якесь «зустрічне» повідомлення. Так, наприклад, при початку DDE-розмови DDE-клієнт передає за допомогою функції SendMessage широкомовне повідомлення WM_DDE_INITIATE, а DDE-сервер відповідає на це повідомлення передачею повідомлення WM_DDE_ACK, якщо він підтримує необхідний DDE-розмова. Тобто обробник повідомлення WM_DDE_INITIATE сервера передає за допомогою той-же функції SendMessage повідомлення WM_DDE_ACK вікна клієнта, яке в даний момент чекає кінця обробки переданого їм повідомлення WM_DDE_INITIATE . При цьому було б можливим зависання обох потоків, так як потік клієнта зупинений до кінця обробки переданого їм WM_DDE_INITIATE, а потік сервера буде чекати, поки зупинений потік клієнта не відповість на зустрічну повідомлення WM_DDE_ACK, яке він передає в якості підтвердження. Що б уникнути подібних неприємностей функція SendMessage може обробляти повідомлення, передані даного потоку іншими потоками, перебуваючи в очікуванні відповіді від обробника переданого повідомлення. Застій потоків при обміні повідомленнями таки можливий. Така ситуація легко може статися при використанні MDI: в Win32 для кожного відкритого дочірнього MDI-вікна автоматично створюється свій власний потік. В цьому випадку при використанні функції SetFocus для передачі фокуса від одного дочірнього MDI-вікна іншому дочірньому MDI-вікна (природно належить іншому потоку) відбувається обмін повідомленнями WM_SETFOCUS і WM_KILLFOCUS, що призводить до зупинки обох потоків. Ця особливість платформи офіційно описана Microsoft. Крім того можливо зависання потоку, що передав повідомлення, якщо потік-одержувач завис сам або зайнятий дуже тривалими операціями. Так як тривала зупинка передавального повідомлення потоку може бути небажана, то в Win32 API описані спеціальні функції для роботи з між потоковими повідомленнями: SendMessageTimeout, SendMessageCallback, SendNotifyMessage і ReplyMessage.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]