Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab6.DOC
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
186.37 Кб
Скачать

Звичайна пам'ять

Функція DOS 48h: Виділити пам'ять

Вхід: АН = 48h.

ВХ = розмір блоку в 16-байтних параграфах

Вихід:CF = 0, якщо блок виділений

AX = сегментна адреса виділеного блоку

CF = 1, якщо виникла помилка:

АХ = 7 - блоки керування пам'яттю зруйновані

АХ = 8 - недостатньо пам'яті:

ВХ = розмір максимального доступного блоку

Ця функція з великим значенням у ВХ (звичайно 0FFFFh) використовується для визначення розміру найбільшого доступного блоку пам'яті.

Функція DOS 49h: Звільнити пам'ять

Вхід: АН = 49h

ES = сегментна адреса блоку, що звільняється

Вихід: CF = 0, якщо блок звільнений

CF = 1, АХ =7, якщо блоки керування пам'яттю зруйновані;

АХ = 9, якщо в ES міститься невірна адреса

Ця функція не дозволить звільнити блок пам'яті, яким поточна програма не володіє, але за допомогою функції DOS 50h (AX = 50h, ВХ - сегментна адреса PSP процесу) програма може «прикинутися» будь-яким іншим процесом.

Функція DOS 4Ah: Змінити розмір блоку пам'яті

Вхід: АН=4Ah

ВХ = новий розмір у 16-байтних параграфах

ES = сегментна адреса блоку, що модифікується

Вихід: CF = 1, якщо при виконанні операції відбулася помилка

АХ = 7, якщо блоки керування пам'яттю зруйновані

АХ = 8, якщо не вистачає пам'яті (при збільшенні)

АХ = 9, якщо ES містить невірна адреса

ВХ = максимальний розмір, доступний для цього блоку

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

При запуску COM-програми виділяється найбільший доступний блок пам'яті для цієї програми, так що при роботі з основною пам'яттю ці функції вимагаються рідко (в основному для того, щоб скоротити виділений програмі блок пам'яті до мінімуму перед завантаженням іншої програми), але вже в MS DOS 5.0 і далі за допомогою цих же функцій можна виділяти пам'ять в областях UMB - невикористовуваних ділянках пам'яті вище 640 Кб і нижче 1 Мб, для чого потрібно спочатку підключити UMB до менеджера пам'яті і змінити стратегію виділення пам'яті за допомогою функції DOS 58h.

Область пам'яті UMB

Функція DOS 58h: Прочитати/змінити стратегію виділення пам'яті

Вхід: АН=58h

AL = 00h - прочитати стратегію

AL = 01h - змінити стратегію

ВХ = нова стратегія

біти 2-0:

00 - перший придатний блок

01 - найбільш придатний блок

11 - останній придатний блок

біти 4-3:

00 - звичайна пам'ять

01 - UMB (DOS 5.0+)

10 - UMB, потім звичайна пам'ять (DOS 5.0+)

AL = 02h - прочитати стан UMB

AL = 03h - встановити стан UMB

ВХ - новий стан: 00 - не використовуються, 01 - використовуються

Вихід: CF = 0, АХ - поточна стратегія для AL =0, стан UMB для AL = 2

CF = 1, AX = 01h, якщо функція не підтримується

Якщо програма змінювала стратегію виділення чи пам'яті стан UMB, вона обов'язково повинна їх відновити перед закінченням роботи.

Область пам'яті нма

Область пам'яті від 0FFFFh:0010h (кінець першого мегабайта) до 0FFFFh:0FFFFh (кінець адресного простору в реальному режимі), 65 520 байт, може використовуватися на комп'ютерах, починаючи з 80286. Доступ до цієї області здійснюється за допомогою специфікації XMS, причому уся вона виділяється цілком одній програмі.

INT 2Fh, AX = 4A01h: Визначити розмір доступної частини НМА (DOS 5.0+)

Вхід: АХ=4A01h

Вихід: ВХ - розмір доступної частини НМА в байтах, 0000h, якщо DOS не В НМА

ES:DI = адреса початку доступної частини НМА (0FFFFh:0FFFFh, якщо DOS

не в НМА)

INT 2Fh, AX = 4A02h: Виділити частину НМА (DOS 5.0+)

Вхід: АХ=4A02h

ВХ = розмір у байтах

Вихід: ES:DI - адреса початку виділеного блоку

ВХ - розмір виділеного блоку в байтах

У версіях DOS 5.0 і 6.0 немає функцій звільнення виділених у такий спосіб блоків НМА.

У DOS 7.0 (Windows 95) виділення пам'яті в НМА було організовано аналогічно виділенню пам'яті в звичайній пам'яті і UMB, з функціями зміни розміру і звільнення блоку.

INT 2Fh, AX = 4A03h: Керування розподілом пам'яті в НМА (DOS 7.0+)

Вхід: AX =4A03h

DL = 0 - виділити блок (ВХ = розмір у байтах)

DL = 1 - змінити розмір блоку (ES:DI = адреса, ВХ = розмір)

DL = 2 - звільнити блок (ES:DI = адреса)

СХ - сегментна адреса власника блоку

Вихід: DI = 0FFFFh, якщо не вистачило пам'яті, ES:DI адреса блоку (при виділенні)

Інтерфейс EMS

Розширена пам'ять (EMS) - додаткова можливість для програм, що запускаються в реальному режимі (чи в режимі V86), звертатися до пам'яті, що перебуває за межами першого мегабайта. EMS дозволяє відобразити сегмент пам'яті, що починається з 0D000h, на будь-які ділянки пам'яті, аналогічно тому, як здійснюється доступ до відеопам'яті в SVGA-режимах. Викликати функції EMS (переривання 67h) дозволяється, тільки якщо в системі присутній драйвер з ім'ям ЕММХХХХО. Для перевірки його існування можна викликати функцію 3Dh (відкрити чи файл пристрій). Причому на той випадок, якщо драйвер EMS відсутній, а в поточній директорії є файл з ім'ям ЕММХХХХО, варто додатково викликати функцію IOCTL -INT 21h з AX =4400h і ВХ = ідентифікатор файлу або пристрою, отриманий від функції 3Dh. Якщо значення біта 7 у DX після виклику цієї функції дорівнює 1, то драйвер EMS напевно є присутнім у системі.

Основні функції EMS:

INT 67h, АН = 46h: Одержати номер версії

Вхід: АН=46h

Вихід: АН = 0 і AL - номер версії в упакованому BCD (40h для 4.0).

В усіх випадках, якщо, АН не нуль, відбулася помилка

INT 67h, АН = 41h: Одержати сегментну адресу вікна

Вхід: АН-41h

Вихід: АН = 0 і ВХ = сегментна адреса вікна

INT 67h, АН = 42h: Одержати обсяг пам'яті

Вхід: АН=42h

Вихід: АН=0

DX = обсяг EMS-пам'яті в 16-кілобайтних сторінках

ВХ = обсяг вільної EMS-пам'яті в 16-кілобайтних сторінках

INT 67h, АН = 43h: Виділити ідентифікатор і EMS-пам'ять

Вхід: АН=43h

ВХ = необхідне кількість 16-кілобайтних сторінок

Вихід: АН = 0, DX = ідентифікатор

Тепер зазначений у цій функції набір сторінок у EMS-пам'яті описується як зайнятий і інші програми не зможуть його виділити для себе.

INT67h, АН = 44h: Відобразити пам'ять

Вході AH=44h

AL = номер 16-кілобайтної сторінки в 64-кілобайтному вікні EMS (0-3)

BX = номер 16-кілобайтної сторінки в EMS-пам'яті

DX = ідентифікатор

Вихід: АН= 0

Далі запис/читання в зазначену сторінку в реальному адресному просторі приведе до запису/читанню в зазначену сторінку в EMS-пам'яті.

INT 67h, АН = 45h: Звільнити ідентифікатор і EMS-пам'ять

Вхід: АН=45h

DX = ідентифікатор

Вихід: АН = 0

Специфікація EMS була розроблена для комп'ютерів IBM XT, що забезпечувалися особливою платою, на якій і знаходилася розширена пам'ять. З появою процесора 80286 стало можливим установлювати більше одного мегабайта пам'яті на материнській платі, і для роботи з нею була введена нова специфікація - XMS. Тоді ж були створені менеджери пам'яті, які емулювали EMS поверх XMS, для сумісності зі старими програмами, причому робота через EMS виконувалася повільніше. Пізніше, коли в процесорах Intel з'явився механізм сторінкової адресації, з'ясувалося, що EMS можна реалізувати набагато швидше XMS. Більшість програм для DOS, яким потрібно додаткова пам'ять, підтримують обидві специфікації.

Інтерфейс XMS

Специфікація доступу до додаткової пам'яті (XMS) - ще один метод, що дозволяє програмам, що запускаються під керуванням DOS у реальному режимі (чи в режимі V86), використовувати пам'ять, розташовану вище границі першого мегабайта.

INT 2FH, АН = 43 XMS -сервіс

Вхід: АХ = 4300h: перевірити наявність XMS

Вихід: АН = 80h, якщо HIMEM.SYS чи сумісний драйвер завантажений

Вхід: AX = 4310h: одержати точку входу XMS

Вихід: ES:BX = далека адреса точки входу XMS

Після визначення точки входу усі функції XMS викликаються за допомогою команди CALL на зазначену далеку адресу.

Функція XMS 00h: Визначити номер версії

Вхід: AH= 00h

Вихід: АХ = номер версії, не упакований BCD (0300h для 3.0)

ВХ - внутрішній номер модифікації

DX = 1, якщо НМА існує; 0 - немає

Функція XMS 08h: Визначити об’єм пам'яті

Вхід: АН=08h

BL=00h

Вихід:АХ = розмір максимального доступного блоку в кілобайтах

DX= розмір XMS-пам'яті усього в кілобайтах

BL = код помилки (0A0h, якщо вся XMS-пам'ять зайнята 00 - якщо немає помилок)

Тому що розмір пам'яті, виявляється обмеженим розміром слова (65 535 Кб), починаючи з версії XMS 3.0, введена більш точна функція 88h.

Функція XMS 88h: Визначити об’єм пам'яті

Вхід: АН = 88h

Вихід:ЕАХ = розмір максимального доступного блоку в кілобайтах

BL = код помилки (0A0h, якщо вся XMS-пам'ять зайнята; 00, якщо немає помилок)

ЕСХ = фізична адреса останнього байта пам'яті (вірний для помилки 0A0h)

EDX = розмір XMS-пам'яті в кілобайтах (0 для помилки 0A0h)

Функція XMS 09h: Виділити пам'ять

Вхід: АН=09h

DX = розмір запитуваного блоку (у кілобайтах)

Вихід:АХ = 1, якщо функція виконана

DX = ідентифікатор блоку

АХ = 0:

BL = код помилки (0A0h, якщо не вистачило пам'яті)

Функція XMS 0Ah: Звільнити пам'ять

Вхід: АН=0Ah

DX = ідентифікатор блоку

Вихід:АХ = 1, якщо функція виконана.

Інакше - АХ = 0 і BL = код помилки (0A2h - неправильний ідентифікатор, 0ABh - ділянка заблокована)

Функція XMS 0Bh: Пересилання даних

Вхід: АН = 0Bh

DS:SI = адреса структури для пересилання пам'яті

Вихід: АХ = 1, якщо функція виконана

Інакше - АХ =О и BL = код помилки

Структура даних, адреса яких передається в DS:SI:

+00h: 4 байти - число байтів для пересилання

+04h: слово - ідентифікатор джерела (0 для звичайної пам'яті)

+06h: 4 байти - зміщення у джерелі або адреса в пам'яті

+0Ah: слово - ідентифікатор приймача (0 для звичайної пам'яті)

+0Ch: 4 байти - зміщеннія у приймачі чи адреса в пам'яті

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

Функція XMS 0Fh: Змінити розмір XMS-блоку

Вхід: AH=0Fh

ВХ - новий розмір

DX = ідентифікатор блоку

Вихід: АХ=1, якщо функція виконана.

Інакше - АХ = 0 і BL - код помилки

Крім того, XMS дозволяє програмам використовувати область НМА і блоки UMB, якщо вони не зайняті DOS при запуску.

Завдання 2. ( 3 рівень)

1. Наберіть наведену нище програму.

; mem.asm

; повідомляє розмір пам'яті, доступної через EMS і XMS

.model tiny

.code

.186 ; для команд зміщення на 4

org 100h ; COM-програма

start:

cld ; команди строкової обробки будуть виконуватися вперед

; перевірка наявності EMS

mov dx,offset ems_driver ; адреса ASCIZ-рядка "EMMXXXX0"

mov ax,3D00h

int 21h ; відкрити файл чи пристрій

jc no_emmx ; якщо не удалося відкрити - EMS немає

mov bx,ax ; ідентифікатор у BX

mov ax,4400h

int 21h ; IOCTL: перевірити стан файлу/пристрою

jc no_ems ; якщо не було помилка,

test dx,80h ; перевірити старший біт DX,

jz no_ems ; якщо він - 0, EMMXXXX0 - файл у поточній

; директорії

; визначення версії EMS

mov ah,46h

int 67h ; одержати версію EMS

test ah,ah

jnz no_ems ; якщо EMS видав помилку - не варто продовжувати з

; ним працювати

mov ah,al

and al,0Fh ; AL = старша цифра

shr ah,4 ; AH = молодша цифра

call output_version ; видати рядок про номер версії EMS

; визначення доступної EMS-пам'яті

mov ah,42h

int 67h ; одержати розмір пам'яті в 16-кілобайтних сторінках

shl dx,4 ; DX = розмір пам'яті в кілобайтах

shl bx,4 ; BX = розмір вільної пам'яті в кілобайтах

mov ax,bx

mov si,offset ems_freemem ; адреса рядка для output_info

call output_info ; видати рядки про розміри пам'яті

no_ems:

mov ah,3Eh

int 21h ; закриємо файл/пристрій EMMXXXX0

no_emmx:

; перевірка наявності XMS

mov ax,4300h

int 2Fh ; перевірка XMS,

cmp al,80h ; якщо AL не дорівнює 80h,

jne no_xms ; XMS відсутня,

mov ax,4310h ; інакше:

int 2Fh ; одержати точку входу XMS

mov word ptr entry_pt,bx ; і зберегти її в entry_pt

mov word ptr entry_pt+2,es ; (старше слово - по старшій

; адресі)

push ds

pop es ; відновити ES

; визначення версії XMS

mov ah,00

call dword ptr entry_pt ; Функція XMS 00h - номер версії

mov byte ptr mem_version,'X' ; змінити першу букву рядка

; "EMS detected" на 'X'

call output_version ; видати рядок про номер версії XMS

; визначення доступної XMS-пам'яті

mov ah,08h

xor bx,bx

call dword ptr entry_pt ; Функція XMS 08h

mov byte ptr totalmem,'X' ; змінити першу букву рядка

; "EMS total" на 'X'

mov si,offset xms_freemem ; рядок для output_info

; виведення повідомлень на екран:

; DX - обсяг всієї пам'яті

; AX - обсяг вільної пам'яті

; SI - адреса рядка з повідомленням про вільну пам'ять (різна для EMS і XMS)

output_info:

push ax

mov ax,dx ; обсяг усієї пам'яті в AX

mov bp,offset totalmem ; адреса рядка - у BP

call output_info1 ; виведення

pop ax ; обсяг вільної пам'яті - у AX

mov bp,si ; адреса рядка в BP

output_info1: ; виведення

mov di,offset hex2dec_word

; hex2dec

; перетворити ціле двійкове число в AX

; у рядок десяткових ASCII-цифр у ES:DI, що закінчується символом '$'

mov bx,10 ; дільник у BX

xor cx,cx ; лічильник цифр у 0

divlp: xor dx,dx

div bx ; розділити преутворюване число на 10

add dl,'0' ; додати до залишку ASCII-код нуля

push dx ; записати отриману цифру в стек

inc cx ; збільшити лічильник цифр

test ax,ax ; і, якщо ще є, що ділити,

jnz divlp ; продовжити ділення на 10

store:

pop ax ; прочитати цифру із стека

stosb ; дописати її в кінець рядка в ES:DI

loop store ; продовжити для всіх CX-цифр

mov byte ptr es:[di],'$' ; дописати "$" у кінець рядка

mov dx,bp ; DX - адреса першої частини рядка

mov ah,9

int 21h ; Функція DOS 09h - виведення рядка

mov dx,offset hex2dec_word ; DX - адреса рядка з десятковим

; числом

int 21h ; виведення рядка

mov dx,offset eol ; DX - адреса останньої частини рядка

int 21h ; виведення рядка

no_xms: ret ; кінець програми і процедур output_info

; і output_info1

; виведення версії EMS/XMS

; AX - номер у неупакованому BCD-форматі

output_version:

or ax,3030h ; перетворення неупакованого BCD у ASCII

mov byte ptr major,ah ; старша цифра в major

mov byte ptr minor,al ; молодша цифра в minor

mov dx,offset mem_version ; адреса початку рядка - у DX

mov ah,9

int 21h ; виведення рядка

ret

ems_driver db 'EMMXXXX0',0 ; ім'я драйвера для перевірки EMS

mem_version db 'EMS version ' ; повідомлення про номер версії

major db '0.' ; перші байти цього

minor db '0 detected ',0Dh,0Ah,'$'; і цього рядків будуть

; замінені реальними номерами версій

totalmem db 'EMS total memory: $'

ems_freemem db 'EMS free memory: $'

eol db 'K',0Dh,0Ah,'$' ; кінець рядка

xms_freemem db 'XMS largest free block: $'

entry_pt: ; сюди записується точка входу XMS

hex2dec_word equ entry_pt+4 ; буфер для десяткового рядка

end start

2. Проаналізувати программу за допомогою TD.

3. Разібрати логіку работи програми.

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

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