Дипломная работа по предмету "Информатика, программирование"


Вивід вмісту каталогу y середовищі MS DOS

зміст


вступ............................................................................................................. 3


1. Постановка задачі............................................................................ 4


2. Програмний інструментарій........................................................ 5


2.1. Вибір засобу виконання поставленої задачі........................................... 5


2.2. Функції переривання INT21hMSDOS, що використані при роботі програм.......................................................................................................................... 5


2.2.1. Функції роботи із DTA.......................................................................... 5


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


3. Розробка задачі на мові асемблер.......................................... 10


3.1. Допоміжні процедури............................................................................ 10


3.1.1. Модуль PARAMS.asm........................................................................ 10


3.1.2. Модуль STRIO.asm............................................................................. 14


3.1.3. Модуль BINASC.asm.......................................................................... 17


3.2. Розробка основної програми DR.asm................................................... 20


4. Розробка задачі на мові високого рівня із використанням асемблерних фрагментів коду..................................................... 30


4.1. Розробка програми на Pascal................................................................ 30


Висновки.................................................................................................. 34


Список використаних джерел...................................................... 35


Додатки..................................................................................................... 36


вступ


Еволюція мов програмування нараховує вже не один десяток років. Пройдено великий етап від мов структурного програмування (таких як С) до систем багатомовного програмування, на роль яких претендують такі бренди як С#, Java, та ін. Однак слід зазначити, що незважаючи на постійне оновлення мов високого рівня щодо їх пристосування до зростаючих потреб програмістів, головна їх задача лишається тією ж самою – транслювати свої команди у машинний код. Тобто, не має ніякої різниці, якою мовою виконувати задачу – результат лишається той же; відмінність полягає лише у тому, як ця мова інтерпретує рішення програміста у мову машинних кодів. Тому відповідь на питання – чому мова асемблера, залишаючись практично незмінною у своїй ідеології і лексичній базі (цього не можна сказати, наприклад, про сімейство С), лишається й досі конкурентноспроможною іншим мовам – є цілком зрозумілою: вона, як мова програмування низького рівня, найближча до мови комп'ютера і, наразі, найбільш ефективна.


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


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


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


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



1. Постановка задачі


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


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


Програми мають містити коментарі і схеми алгоритмів.



2. Програмний інструментарій


2.1. Вибір засобу виконання поставленої задачі


Існує два шляхи вирішення поставленої задачі. Розглянемо кожний з них окремо.


Перший засіб


Послідовне переміщення по дереву каталогу шляхом безпосереднього читання (за допомогою другої функції переривання INT13hBIOS) секторів пам'яті, починаючи із ROOT, і пошуку необхідного підкаталогу згідно із вказаним шляхом до потрапляння у кінцевий каталог із виводом даних о всіх файлах і директоріях, що в ньому містяться [1, 2].


Однак даний метод надзвичайно складний, має прив'язку до певної системи FAT, організації BOOTі таблиці розділів, потребує прямого звертання до жорсткого диску, що не свідчить в його користь.


Другий засіб


Пов'язаний із специфікою роботи MSDOS. Коли програма починає виконуватись, регістри DS:0000 і ES:0000 вказують на початок PSP(ProgramSegmentPrefix– префікс програмного сегмента) – об'єм пам'яті, в якому міститься інформація о розмірі доступної пам'яті, опції із рядка команд, імена файлів, оточення, а також DTA(розмір 43 байти) [4, 6].


DTAмає наступну структуру:


- Резервна область.


- Атрибут.


- Час створення файлу.


- Розмір файлу.


- Ім'я із розширенням файлу.


Таким чином DTAдає повну і вичерпну інформацію о файлі. Тобто, читаючи послідовно DTAкожного файлу директорії, можна отримати інформацію по кожному файлу і вивести її на екран.


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


2.2. Функції переривання
INT
21
h
MS
DOS
, що використані при роботі програм


2.2.1. Функції роботи із
DTA


Середовище MSDOSпропонує набір функцій переривання INT21h, що дозволяють працювати із DTA– встановити його адресу (1Ah), дати поточний DTA(2Fh), заповнити DTAпри знаходженні першого файлу (4Eh), заповнити DTAпри знаходженні наступного файлу (4Fh). Розглянемо кожну з цих функцій окремо:


1Ahфункція INT21h[6]


Вхід: AH1Ah


DS:DXадреса для DTA


Вихід:не має


Дана функція встановлює адресу для DTA. В регістрову пару DS:DXзаноситься, відповідно, сегмент і зміщення буфера розміром >43 байтів, в який буде зберігатись DTA. Якщо адреса DTAзмінюється вашою програмою, бажано зберегти попередню адресу DTA(за допомогою функції 2FhINT21h) і відновити її після завершення програми.


Приклад:


movah, 1Ah ; в ahномер функції


movdx, offsetbuffer ; в dxпоміщується зміщення буфера,


; сегмент лишається незмінний


int21h


В даному прикладі перевизначається адреса для буфера DTA.


2Fhфункція INT21h[6]


Вхід: AH2Fh


Вихід: ES:BSадреса початку поточної DTA.


Функція повертає адресу початку області вводу/виводу DTA. В AHзаноситься номер функції; в регістровій парі ES:BSповертається адреса початку DTA.


Дана функція корисна при збереженні адреси DTAдля її подальшого відновлення після зміни програмою. Слід бути обережним при її використанні, оскільки функція змінює регістр es.


Приклад:


pushes ; збереження у стеку регістрів es, bx, що зміняться


pushbx


movah, 2Fh ;в ах номер функції


int21h


mov[DTAs], es ; збереження адреси DTA


mov[DTAo], bx


popbx ; відновлення попередніх значень регістрів bxі es


popes ; із стеку


В даному прикладі у змінних DTAsі DTAoзберігається адреса DTA, регістри bx, esнезмінні.


4Ehфункція INT21h[6]


Вхід: AH4Fh


DS:DXадреса ASCIIрядка із маскою імені файлу


СХ атрибут файлу для порівняння


Вихід: АХ код помилки, якщо в CF=1 буфер DTAзаповнений даними.


Дана функція знаходить ім'я першого файлу у переліку, що відповідає заданій масці і атрибуту, і поміщує інформацію про нього в буфер DTA. В AHпоміщується номер функції; регістрова пара вказує на рядок, що задає маску імені файлу; в СХ міститься атрибут файлу.


В імені файлу і розширенні допускаються узагальнені символи "*" і "?".


Функція повертає код помилки в AX, якщо файл не знайдений, або заповнює буфер DTAданими про файл.


4Fhфункція INT21h[6]


Вхід: AH4Fh


DS:DXадреса даних, повернутих попередньою 4Eh


функцією INT21h


Вихід: AXкод помилки, якщо CF=1


DTAзаповнена даними


Дана функція викликається після функції 4EhINT21hі знаходить наступний файл, що відповідає параметрам пошуку, заданим при визові 4EhINT21h.


В AHзаноситься номер функції, в регістрову пару DS:DX– адреса даних, повернутих попередньою функцією.


Функція повертає в AXкод помилки, якщо вона не відбулась, або поміщує в буфер DTAдані про файл, що відповідає узагальненому імені і атрибуту.


Приклад:


movah, 4Eh ; в аhномер функції першого пошуку


movdx, affsetmask ; в dxзміщення маски


mov cx, 10h


int 21h


jc end


@@01:


movah, 4Fh ; ваhномер функції наступного пошуку


int21h


jnc@@01


end:


Приклад демонструє перегляд каталогу на наявність файлів, що відповідають масці, заданої змінною mask. В буфері DTAзалишається опис останнього знайденого файлу.


2.2.2. Інші функції переривання
INT
21
h
, що необхідні для використання у програмі, що розробляється


2hфункція INT21h[6]


Вхід: AH02h


DLкод символу, що виводиться на вивід


Вихід: символ на екрані


В AHпоміщується код функції, в DLкод символу, що необхідно вивести на екран.


Слід відмітити, що при наявності в DLкоду 8 (ASCIIкод Backspace) функція переміщує курсор вліво на одну позицію.


Для виконання переходу на новий рядок слід послідовно вивести символи із кодами 13 і 10 на екран[5].


Приклад:


movah, 2 ; номер функції


movdl, 13 ; вертикальна табуляція


int 21h


movdl, 10 ; зсув каретки


int 21h


Даний фрагмент коду переводить курсор на новий рядок.


40hфункція INT21h[6]


Вхід: AH 40h


BX описувач файлу


DS:DXадреса буфера, що містить дані, що записуються


CX число байт, що записуються


Вихід: AX код помилки, якщо CF=1


ALчисло реально зчитаних байт


Дана функція записує CXбайт даних в файл, або пристрій, заданий описувачем в BX. В AHпоміщується номер функції, BXмістить описувач[6]:


0 Стандартний пристрій вводу (звичайна клавіатура)


1 Стандартний пристрій виводу (звичайний екран)


2 Стандартний пристрій помилок (CON-екран)


3 Стандартний пристрій AUX(COM1)


4 Стандартний принтер (LPT1)


Регістрова пара DS:DXадресується на буфер. В CXміститься кількість записуваних байт.


Функція повертає в AXкод помилки при умові, що CFвстановився в 1, або кількість реально зчитаних байтів в AL.


Для нас дана функція цікава як інструмент для виводу даних на екран, тому в BXмає бути занесено 1.


Приклад:


movah, 40h ; код функції


movbx, 1 ; вивід на екран


movdx, offsetsstring ; в dxзміщення рядка виводу


movcx, FFh ; в cxкількість символів, що виводяться


int 21h


Даний фрагмент коду виводить на екран рядок символів, що містяться в змінній sstring.


4Chфункція INT21h[6]


Вхід: AH 4Ch


AL код виходу


Вихід: не має


Функція завершення програми (EXIT). Повертає управління від породженого процесу його батьківському процесу. Встановлює код виходу (його можна опитати функцією WAIT(4Dh)).


В AХміститься номер функції, в AL– код виходу:


0 нормальне завершення


1 завершення через Ctrl-Break(INT23h)


2 завершення по критичній помилці пристрою (INT24h)


3 завершення через функцію KEEP(31h)


Приклад:


movax, 04ch ; в al– код виходу


int 21h ; в ah– номер функції


Даний фрагмент коду задає нормальне завершення роботи програми (повертається код виходу – 0).


3. Розробка задачі на мові асемблер


3.1. Допоміжні процедури


Очевидно, що основна програма потребує допоміжні процедури для отримання необхідних параметрів, які задає користувач в командному рядку при визові програми. Серед них: процедури вводу/виводу даних на консоль, обробки ASCIIрядків, а також перетворення числових даних у ASCIIформат для подальшого їх виведення на екран. Для цього були розроблені спеціальні модулі PARAMS.asm, STRIO.asmта BINASC.asm, які містять необхідні процедури. Розглянемо їх окремо.


3.1.1. Модуль
PARAMS
.
asm


Традиційно, програми MSDOSдозволяють користувачу вводити в командному рядку одне чи більше імен файлів і інші дані. Для нас це цікаве можливістю одразу при визові основної програми DR.exeзадавати шлях до директорії та маску файлів, які ми бажаємо вивести на екран[7].


Наприклад:


c > DR c:\windows\*.sys


Тобто даний ввід має викликати програму DR.exe, яка виведе усі файли із розширенням .sys, які знаходяться за адресою c:\windows. Мова асемблера не дає нам вбудованих механізмів реалізації даної можливості, тому виникає необхідність розробки власного програмного модуля для роботи із командним рядком.


При завантаженні exe-файлу command.comстворює в пам'яті PSPблок (256 байт), у якому, серед іншої інформації, містить текст, який йде після імені програми (хвіст команди). Перед початком виконання програми адреса PSPміститься в регістровій парі ds:es. Хвіст команди починається зі зміщення 80h(до FFh)і займає 128 байт, при чому перший символ знаходиться за зміщенням 81h, а в 80hміститься кількість символів хвоста команди[4, 6].


Ідея модуля PARAMS.asmв тому, що створюється власний 128-ми байтовий буфер, в який (за допомогою функції GetParams) копіюється хвіст команди, а потім виконується обробка отриманих даних за допомогою функції GetOneParam(отримання адреси параметра за номером) і ParamCount(отримання кількості параметрів).


Параметри в хвості команди розділені пробілами, останній символ – символ повернення каретки.


На основі сказаного було розроблено наступний програмний модуль:


IDEAL


MODELsmall


TailLenEQU0080h ; зміщення байта із довжиною рядка


; параметрів


CommandTailEQU0081h ; зміщення першого символу рядка


; параметрів


DATASEG


numParamsDW? ; кількість параметрів


paramsDB128 DUP(?) ; буфер на 128 байт для хвоста команди


CODESEG


PUBLIC ParamCount, GetParams, GetOneParam


; -------------------------------------------------------------------------------------------


; Separators внутрішня процедура для перевірки на пробіли, табуляцію,


; повернення каретки


; ------------------------------------------------------------------------------------------


; Вхід ds:si адреса символу, що перевіряється


; Вихід ZF=1 символ є пробілом, табуляцією чи поверненням каретки


ZF=1 символ не є роздільником


; Регістри не змінюються


; -------------------------------------------------------------------------------------------


PROC Separators


push ax ; збереження у стеку ax


moval, [si] ; в alпоміщується символ із ds:si


cmpal, 020h ; порівняння alіз пробілом


je @@10 ; якщо так, то перехід


cmpal, 009h ; порівняння alіз табуляцією


je @@10 ; якщо так, то перехід


cmpal, 00Dh ; порівняння alіз символом повернення


; каретки


@@10:


popax ; відновлення ax


ret ; повернення до викликаючої програми


ENDPSeparators


; -------------------------------------------------------------------------------------------


; ParamCount повертає кількість параметрів у хвості команди


; -------------------------------------------------------------------------------------------


; Вхід не має


; Вихід CX кількість параметрів командного рядка


; Регістри CX


; -------------------------------------------------------------------------------------------


PROCParamCount


movcx, [numParams] ; отримати значення змінної numParams


ret ; повернення до викликаючої програми


ENDPParamCount


; -------------------------------------------------------------------------------------------


; GetParams занесення параметрів командного рядка DOSу буфер


; -------------------------------------------------------------------------------------------


; Вхід ds префікс сегмента програми (PSP) (адресує PSP, якщо його


; не змінювали)


; es сегмент даних програми


; Вихід [params] початок буфера заповненого даними


; [numParams] кількість параметрів


; ds сегмент даних програми


; Регістри al, bx, dx, si, di, ds


; -------------------------------------------------------------------------------------------


PROCGetParams


;------Ініціалізація cxі індексних регістрів siі di


pushax ; збереження регістрів


pushbx


push dx


push si


push di


xor ch, ch ; обнуління верхньої половини cx


movcl, [ds:TailLen] ; в cxдовжина параметрів


inccx ; включити символ повернення каретки


movsi, CommandTail ; адреса параметрів поміщується в si


movdi, offsetparams ; адреса призначення поміщується в di


; ------Пропуск початкових пробілів і табуляції


@@10:


callSeparators ; пропуск пробілів і табуляції


jne @@20 ; перехід, якщо пробілів і табуляції не має


incsi ; пропуск символу


loop @@10 ; цикл, доки не скінчиться обробка, абоcx=0


; ------Копіювання параметрів рядка в буфер params


@@20:


pushcx ; збереження cxу стеку


jcxz @@30 ; пропуск копіювання, якщо cx=0


cld ; збільшення на 1 siі di


repmovsb ; копіювання cxбайтів із ds:siв es:di


; ------Перетворення пробілів в 0 і встановлення numParams


@@30:


push es


pop ds ; ds=es


popcx ; відновлення cx(довжину)


xorbx, bx ; обнуління bx, лічильник параметрів


jcxz @@60 ; пропуск циклу якщоcx=0 (довжина)


movsi, offsetparams ; поміщення адреси параметрів в si


@@40:


callSeparators ; перевірка на пробіли, табуляцію,


; повернення каретки


jne @@50 ; перехід, якщо не знайдено роздільник


mov [byteptrsi], 0 ; заміна роздільника на 0


incbx ; збільшення лічильника кількості


; параметрів


@@50:


incsi ; переміщення указника на наступний


; символ


loop @@40 ; виконувати в циклі, доки cx≠0


@@60:


mov [numParams], bx ; збереження в numParamsкількість


; параметрів


popax ; відновлення регістрів


popbx


popdx


pop si


pop di


ret ; повернення до батьківської програми


ENDPGetParams


; -------------------------------------------------------------------------------------------


; GetOneParam отримати адресу параметра за номером


; -------------------------------------------------------------------------------------------


; Вхід cx номер параметра (має бути менше значення в numParams)


; Вихід di зміщення ASCIIрядка із потрібним параметром


; Регістри di


; -------------------------------------------------------------------------------------------


PROCGetOneParam


pushax ; збереження регістрів axі cx


pushcx


xoral, al ; обнуління al(ініціалізація шуканого


; значення 0)


movdi, offsetparams ; адреса параметрів рядка


jcxz@@99 ; якщо номер параметра(cx) дорівнює 0,


; то вихід


cmpcx, [numParams] ; порівняння cxіз кількістю параметрів


jae @@99 ; вихід, якщо передано неіснуючого


; параметру


cld ; автоматичне збільшення di


@@10:


scasb ; пошук нульового обмежувача


jnz @@10 ; повтор, доки не знайдено 0


loop @@10 ; повтор, доки в cxне буде 0


@@99:


popcx ; відновлення регістрів cx, ax


popax


ret ; повернення до викликаючої програми


ENDPGetOneParam


END


Таким чином, програмний модуль PARAMS.asmє зручним інструментом для реалізації роботи із командним рядком і буде використаний в основній програмі.


3.1.2. Модуль
STRIO
.
asm


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


З цих міркувань було розроблено програмний модуль STRIO.asm, в якому міститься п’ять спеціальних функцій: StrLength (визначає кількість символів, записаних в ASCIIрядку), дві функції виводу ASCII-рядків на екран – StrWriteі StrWrite2, а також функцію NewLine(перехід на новий рядок) та WriteSimv(виводить на екран заданий символ необхідну кількість разів).


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


Код програмного модуля STRIO.ASMприведений нижче:


IDEAL


MODEL small


ASCnull EQU 0 ; ASCIIнуль


ASCcr EQU 13 ; ASCIIсимвол повернення каретки


ASClfEQU 10 ; ASCIIсимвол вертикальної табуляції


; (прогону рядка)


CODESEG


PUBLIC StrLength, StrWrite, StrWrite2, NewLine, WriteSimv


; ------------------------------------------------------------------------------------------


; StrLength підраховує кількість ненульових символів в рядку


; -------------------------------------------------------------------------------------------


; Вхід di адреса ASCIIрядка


; Вихід cx кількість ненульових символів в рядку


; Регістри cx


; -------------------------------------------------------------------------------------------


PROCStrLength


pushax ; зберегти у стеку змінювані


pushdi ; регістри ax, di


xoral, al ; в alпоміщується шуканий символ 0


mov cx, 0ffffh ; в cxмаксимальна глибина пошуку


cld ; автоматичне збільшення di


repnzscasb ; шукати al, доки [di] або cxне стане 0


not cx ; логічне заперечення cx


dec cx ; зменшення cxна 1 – довжина рядка


popdi ; відновлення регістрів


popax


ret ; повернення до викликаючої програми


ENDP StrLength


; -------------------------------------------------------------------------------------------


; StrWrite вивід рядка на стандартний пристрій виводу


; StrWrite2 вивід заданої кількості символів рядка на консоль


; -------------------------------------------------------------------------------------------


; Вхід di адреса ASCIIрядка


; cx кількість записуваних символів (для StrWrite2)


; Вихід символьний рядок виводиться на стандартний пристрій


; виводу


Регістри cx(для StrWrite)


; -------------------------------------------------------------------------------------------


PROCStrWrite


callStrLength ; встановити в cxдовжину рядка


PROCStrWrite2 ; друга змінна точка входу


pushax ; збереження змінюваних регістрів


pushbx


pushdx


mov bx, 1 ; задання стандартного пристрою виводу


mov dx, di ; адресація ASCIIрядка в ds:dx


movah, 40h ; в axномер функції, що виконує запис


; в файл або на пристрій виводу


int 21h ; виклик 21 переривання DOS


popdx ; відновлення збережених регістрів


popbx ; із стеку


popax


ret ; повернення до визиваючої програми


ENDP StrWrite2


ENDP StrWrite


; -------------------------------------------------------------------------------------------


; NewLine перейти на новий рядок на стандартному пристрої виводу


; -------------------------------------------------------------------------------------------


; Вхід не має


; Вихід на пристрій виводу посилаються символи повернення


; каретки і прогону рядка


; Регістри не має


; -------------------------------------------------------------------------------------------


PROCNewLine


pushax ; збереження регістрів у стек


pushdx


movah, 2 ; в ahномер функції виводу символу у DOS


mov dl, ASCcr ; в dlсимвол повернення каретки


int 21h ; вивести символ повернення каретки


mov dl, ASClf ; в dlсимвол прогону рядку


int 21h ; вивести символ прогону рядку


pop dx ; відновлення регістрів із стеку


pop ax


ret ; повернення до викликаючої програми


ENDP NewLine


; -------------------------------------------------------------------------------------------


; WriteSimv вивід на стандартний пристрій виводу заданий символ


; визначену кількість разів


; -------------------------------------------------------------------------------------------


; Вхід dl код символу


; cx кількість виводів символу


; Вихід на пристрій виводу задану кількість разів посилається


; переданий символ


;Регістри не має


; -------------------------------------------------------------------------------------------


PROCWriteSimv


pushax ; збереження регістрів


pushcx


@@01:


mov ah,02 ; в ahномер функції DOSзапису символу


int 21h ; вивести заданий символ


loop @@01 ; повторювати доки cx≠0


popcx ; відновлення регістрів


popax


ret ; повернення до викликаючої програми


ENDP WriteSimv


END


Функції, надані програмним модулем STRIO.asm, є зручними і простими інструментами виводу інформації на стандартний пристрій виводу і будуть використані в основній програмі.


3.1.3. Модуль
BINASC
.
asm


Мови високого рівня надають програмісту можливість безпосередньо зчитувати і виводити числові значення. Нажаль, мова асемблера таких інструментів не має. В основній програмі значна частина роботи пов’язана з виводом із деякого буфера даних на екран . Однак дані в буфері зберігаються у вигляді двійкових слів того чи іншого типу. З'являється необхідність перетворення двійкових даних у ASCII-рядки, щоб у подальшому їх можна було вивести на екран. Дану проблему і покликані вирішити функції модуля BINASC.asm. Модуль складається із чотирьох функцій: допоміжних функцій HexDigit(перетворення чотирьохбітового значення у ASCII-цифру) і NumToAscii(перетворення беззнакового двійкового числа у ASCII-рядок), а також двох функцій BinToAscHexі BinToAscDec, які встановлюють систему числення і викликають вищезгадані функції.


Слід зазначити, що функція BinToAscDecзручна для перетворення і подальшого виводу чисел типу "слово" у вигляді десяткового числа.


Функцію BinToAscHexможна використовувати для виводу подвійного слова у вигляді шістнадцятирічного числа, послідовно перетворюючи і виводячи спочатку молодші два, а потім і старші байти, на екран.


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


Код програмного модуля BINASC.asmприведено нижче:


IDEAL


MODEL small


ASCnull EQU 0 ; нульовий ASCII-символ


DATASEG


CODESEG


PUBLIC HexDigit, NumToAscii


PUBLIC BinToAscHex, BinToAscDec


; -------------------------------------------------------------------------------------------


; HexDigit перетворює чотирьохбітове значення в ASCII-цифру


; -------------------------------------------------------------------------------------------


; Вхід dlзначення від 0 до 15


; Вихід dl шістнадцятирічний еквівалент ASCII-цифри


; Регістри dl


; -------------------------------------------------------------------------------------------


PROCHexDigit


cmpdl, 10 ; перевірка, чи є dl< 10


; (тобто менше шістнадцятирічного 'А')


jb @@10 ; якщо так, то перехід


add dl, 'A'-10 ; перетворити в A, B, C, D, EабоF


ret ; повернення до викликаючої програми


@@10:


or dl, '0' ; перетворити в числа від 0 до 9


ret ; повернення до викликаючої програми


ENDP HexDigit


; -------------------------------------------------------------------------------------------


; NumToAscii перетворює беззнакове двійкове значення у ASCII-рядок


; згідно із заданою системою числення


; -------------------------------------------------------------------------------------------


; Вхід ax двохбайтове число, яке перетворюється


; bx основа системи числення результату (2 – двійкова,


; 10 – десяткова, 16 – шістнадцятирічна)


; cx мінімальна кількість цифр, що виводяться


; di адреса рядка для результату


; Вихід di вказує на новостворений рядок із результатом


; Регістри не має


; -------------------------------------------------------------------------------------------


PROCNumToASCII


pushdx ; збереження змінюваних регістрів


pushdi


push si


xor si, si ; встановити лічильник цифр у стеку в 0


jcxz @@20 ; якщо cx= 0, то перехід


@@10:


xor dx, dx ; обнуління dx; axрозширюється до


; 32-х-бітногоdxax


div bx ; в axрезультат ділення на bx, в dxзалишок


call HexDigit ; перетворення числа в dlв ASCII-пару


push dx ; збереження цифри в стеку


inc si ; збільшення лічильника цифр у стеку


loop @@10 ; виконувати цикл, доки не оброблена


; мінімальна кількість цифр


@@20:


inc cx ; встановити cx=1, якщо не усі цифри


; оброблені


or ax, ax ; перевірка axна обробку всіх цифр


jnz @@10 ; якщо ax≠a, продовження перетворень


mov cx, si ; в cxпоміщується кількість цифр у стеку


jcxz @@40 ; пропуск наступного циклу, якщо cx=0


cld ; автоматичне збільшення di


@@30:


pop ax ; в axпоміщується цифра із стеку


stosb ; запис цифри в рядок і збільшення di


loop @@30 ; в циклі вивід cxцифр


@@40:


mov [byte di], ASCnull ; записується 0 у кінець рядка


popsi ; відновлення регістрів


popdi


popdx


ret ; повернення до викликаючої програми


ENDPNumToASCII


; -------------------------------------------------------------------------------------------


; BinToAscHex перетворює двійкове значення в шістнадцятирічні


; ASCII-рядки


; -------------------------------------------------------------------------------------------


; Вхід axдвохбайтове значення, що перетворюється


; cx мінімальна кількість чисел, що виводиться


; diадреса рядка для результату


; Вихід di вказує на рядок із сформованим результатом


; Регістри не має


; -------------------------------------------------------------------------------------------


PROCBinToAscHex


movbx, 16 ; в bxвстановити основу шістнадцятирічної


; системи числення - 16


callNumToAscii ; перетворення числа із axв ASCII-рядок,


; на який вказує di


ret ; повернення до викликаючої програми


ENDPBinToAscHex


; -------------------------------------------------------------------------------------------


; BinToAscHex перетворює двійкове значення в десяткові ASCII-рядки


; -------------------------------------------------------------------------------------------


; Вхід axдвохбайтове значення, що перетворюється


; cx мінімальна кількість чисел, що виводиться


; diадреса рядка для результату


; Вихід di вказує на рядок із сформованим результатом


; Регістри не має


; -------------------------------------------------------------------------------------------


PROC BinToAscDec


mov bx, 10 ; в bxвстановити основу десяткової


; системи числення – 10


callNumToAscii ; перетворення числа із axв ASCII-рядок,


; на який вказує di


ret ; повернення до викликаючої програми


ENDPBinToAscDec


END


Таким чином програмний модуль BINASC.asmдає нам спеціальні функції, що дозволяють перетворити і вивести на екран дані із DTA, що описують файли.


3.2. Розробка основної програми
DR
.
asm


Модулі PARAMS.asm, STRIO.asmі BINASC.asmскладають функціональну базу програмних інструментів для розробки основної програми. Згідно із поставленою задачею, програма має знаходити файли, задані маскою, копіювати DTA, що їх описує, у власний буфер, обробляти отримані дані і виводити необхідну інформацію на екран, а потім переходити до наступного файлу, що відповідає масці, доки не обробить всі.


Таким чином задачу можна розбити на 3 частини:


1) Отримання конфігураційних даних із консолі і, при їх відсутності, встановлення стандартної маски файлів;


2) Пошук файлів, що відповідають масці, і заповнення внутрішнього буферу їх DTA(процедура DirEgine);


3) Саме обробка DTA, вивід даних на екран (процедура Action).


Спираючись на викладені міркування, було створено основну програму DR.asm:


IDEAL


MODEL small


STACK 256


FileName EQU 30 ; зміщення імені файлу в буфері dirData


DATASEG


exCode DB 0 ; код виходу


defaultSpec DB '*.*', 0 ; стандартній ASCII-шаблон маски


DTAsegDW ? ; сегмент для DTA


DTAofsDW ? ; зміщення для DTA


dirDataDB 43 DUP(?) ; буфер для запису вмісту каталогу


bufferDB 6 DUP(?) ; буфер для збереження проміжних


; ASCII-рядків


pointDB ' * ',0 ; ASCII-шаблон зірочки


tit1 DB 'The DIRWUER wersion 1.0',10,13,'Romanov Alexander Urievich. KIT-13A NTU"KhPI"',10,13,'Copyright (C) 2005 byRomanovAlexander',0 ; інформація о програмі


tablDB 'FilenameOnRSkrSysTomKatArhTime


DataSize',0 ; заголовок таблиці


CODESEG


EXTRNGetParams:Proc, GetOneParam:Proc, ParamCount:Proc


із params.obj


EXTRNStrLength:Proc, StrWrite:Proc


EXTRNNewLine:Proc, WriteSimv:Proc, StrWrite2:Proc


; із strio.obj


EXTRNBinToAscHex:Proc, BinToAscDec:Proc


; із Binasc.obj


Start:


movax, @data ; встановлює в axадресу сегмента даних


mov es, ax ; встановлює в esадресу сегмента даних


; ------Отримання даних із командного рядка


call GetParams ; отримати параметри із командного рядка


; (ds=PSP)


call NewLine ; перехід на новий рядок


; ------Виведення інформації о програмі


mov di,offset tit1 ; адреса рядка з інформацією о програмі


call StrWrite ; вивід інформації о програмі на консоль


call NewLine ; перехід на новий рядок


; ------Вибір маски


call ParamCount ; отримання в cxчисло параметрів


movdi, offsetdefaultSpec ; встановити diвказівником на


; стандартний шаблон маски


or cx, cx ; перевірка cxна наявність 0


jz @@10 ; якщо cx=0, перехід


xor cx, cx ; обнуління cx(номер параметру)


call GetOneParam ; отримати адресу параметра


; ------Виклик підпрограми обробника


@@10:


movbx, offsetAction ; поміщення в bxадреси процедури Action


callDirEngine ; виклик процедури DirEngineрозгляду


; каталогу


; ------Завершення роботи


Exit:


call NewLine ; перехід на новий рядок


mov ah, 04Ch ; в ahномер функції виходу із програми


moval, [exCode] ; в alкод виходу


int 21h ; виклик DOS, завершення програми


; -------------------------------------------------------------------------------------------


; DirEngine перегляд каталогу


; -------------------------------------------------------------------------------------------


; Вхід cx:bx адреса підпрограми Action


; ds:diадреса ASCII-рядка для пошуку (маска)


; Вихід викликає процедуру Actionпри кожному знаходженні


; файла, що відповідає масці


Регістри ax, cx, dl, di


; -------------------------------------------------------------------------------------------


PROCDirEngine


; ------Виведення заголовку таблиці


pushdi ; збереження diу стеку


movdi,offsettabl ; в diзміщення рядка заголовка таблиці


; ASCII


callStrWrite ; вивід на екран заголовка таблиці


call NewLine


pop di ; відновлення di


; ------Отримання поточного DTA


pushes ; збереження змінюваних регістрів


pushbx


movah, 2Fh ; в ahномер функції DOSотримання DTA


int 21h ; отримати поточний DTA


mov [DTAseg], es ; збереження адреси сегмента DTA


mov [DTAofs], bx ; збереження адреси зміщення DTA


popbx ; відновлення регістрів


popes


; ------Встановлення нового DTAв глобальному 43-байтовому буфері dirData


movdx, offsetdirData ; адреса змінної dirDataпоміщується


; в ds:dx


mov ah, 1Ah ; а ahномер функції DOSвстановлення


; DTA


int 21h ; встановлення нового DTA


; ------Перевірка каталогу на співпадіння імен файлів із маскою в ds:dx


movah, 4Eh ; в ahномер функції DOSпершого


; пошуку


mov cx, 10h ; атрибут файлів і директорій


mov dx, di ; поміщення адреси рядка в ds:dx


jmp short @@20 ; пропуск наступної дії


@@10:


mov ah, 4Fh ; в ahномер функції DOSпродовження


; пошуку


@@20:


int 21h ; пошук першого/наступного входження


jc @@99 ; вихід при помилці, або закінченні


call bx ; виклик процедури Action


jmp @@10 ; повтор дій


@@99:


; ------Відновлення початкової адреси DTA


pushds ; збереження dsу стеку


movds, [DTAseg] ; встановлення старої адреси DTAв ds:dx


movdx, [DTAofs]


movah, 1Ah ; в ahномер функції DOSвстановлення


; DTA


int 21h ; повернення до старої DTA


pop ds ; відновлення ds


ret ; завершення процедури


ENDPDirEngine


; -------------------------------------------------------------------------------------------


; Action виводить дані про файл із буфера dirData


; -------------------------------------------------------------------------------------------


; Вхід dirDataDTAфайла


; Вихід виводить дані про файл (назву, атрибути, дату/час створення,


; розмір)


; Регістри ax, dl, di, cx


; -------------------------------------------------------------------------------------------


PROC Action


push bx ; збереження регістрів


; ------Вивід імені файлу


movdi, offsetdirData+ FileName ; в diзміщення початку імені файлу


callStrWrite ; вивід імені на екран


callStrLength ; отримання в cxдовжини імені


sub cx, 15 ; виявлення на скільки довжина імені


neg cx ; файлу менше поля із 15 символів


mov dl, ' ' ; в dlсимвол пробілу


callWriteSimv ; вивести на екран необхідну, для


; доповнення поля із 15 символів,


; кількість разів


; ------Вивід атрибутів файлу


moval,[offsetdirData+ FileName-9]; в alпоміщується байт атрибуту


mov cx,6 ; в cxкількість значущих бітів у байті


; атрибуту


@@01:


shral,1 ; зсув alвправо,


; в CFпоміщується молодший біт


jb@@02 ; якщо CF=1, то перехід


mov dl, ' ' ; в dlпоміщується пробіл (символ виводу)


push cx ; збереження cxв стеку


mov cx,4 ; поміщення в cxкількості символів для


; виводу (4)


callWriteSimv ; вивід 4-х пробілів


popcx ; відновлення cx


jmp@@03 ; перехід


@@02:


movdi,offsetpoint ; в diпоміщується зміщення змінної point


pushcx ; збереження cx


callStrWrite ; вивід на екран зірочки


pop cx ; відновлення cx


@@03:


loop @@01 ; виконувати цикл, доки cx≠0 (6-ть разів)


; ------Вивід години створення файлу


movbx,[offsetdirData+ FileName-8] ; в bxпоміщується слово часу


; створення файлу


mov ax,bx ; в axпоміщуються слово години


; створення файлу


andax,0f800h ; накладання маски


shrax,11 ; зсув результату (отримали години)


movcx,1


movdi,offsetbuffer ; diвказує на пустий буфер buffer


callBinToAscDec ; передача в змінну buffer10-кового


; ASCII-представлення числа з ax


mov cx,2 ; в cxширина поля виводу


callStrWrite2 ; вивід ASCII-представлення числа з ax


mov cx,1 ; встановлення в cxкількості виводів


mov dl, ':' ; передача в dlсимволу, що виводиться


call WriteSimv ; вивід один раз символу із dl


; ------Вивід хвилин створення файлу


movax,bx ; в axпоміщується слово хвилини


; створення файлу


and ax,7e0h ; накладання маски


shr ax,5 ; зсув результату (отримали хвилини)


movcx,1


movdi,offsetbuffer ; diвказує на пустий буфер buffer


callBinToAscDec ; передача в змінну buffer10-кового


; ASCII-представлення числа з ax


mov cx,2 ; в cxширина поля виводу


callStrWrite2 ; вивід ASCII-представлення числа з ax


mov cx,1 ; встановлення в cxкількості виводів


mov dl, ':' ; передача в dlсимволу, що виводиться


call WriteSimv ; вивід один раз символу із dl


; ------Вивід секунд створення файлу


mov ax,bx ; в axпоміщується слово секунди


; створення файлу


and ax,1fh ; накладання маски


shl ax,1 ; помноження на 2 (отримання секунд із


; двохсекундних одиниць)


movcx,1


movdi,offsetbuffer ; diвказує на пустий буфер buffer


callBinToAscDec ; передача в змінну buffer10-кового


; ASCII-представлення числа з ax


mov cx,3 ; в cxширина поля виводу


callStrWrite2 ; вивід ASCIIпредставлення числа з ax


mov cx,1 ; встановлення в cxкількості виводів


mov dl, ' ' ; передача в dlсимволу, що виводиться


call WriteSimv ; вивід один раз символу із dl


; ------Виведення дня створення файлу


movbx,[offsetdirData+ FileName-6] ; в bxслово дати створення


; файлу


mov ax,bx ; в axслово дня створення файлу


andax,01fh ; накладання маски


movcx,1 ; встановлення мінімальної довжини


; перетворюваного рядка


movdi,offsetbuffer ; в diзміщення пустого буферу


callBinToAscDec ; заповнення буферу buffer10-ковим


; ASCII-представленням числа з ax


mov cx,2 ; в cxширина поля виводу


call StrWrite2 ; вивід ASCIIпредставлення номера дня


mov cx,1 ; в cxкількість виводів


mov dl, '\' ; в dlсимвол для виводу


callWriteSimv ; вивід символу із dlзадану кількість разів


; ------Вивід місяця створення файлу


movax,bx ; в axслово місяця створення файлу


andax,1e0h ; накладання маски


shrax,5 ; зсув результату (отримання місяця)


mov cx,1 ; встановлення мінімальної довжини


; перетворюваного рядка


movdi,offsetbuffer ; в diзміщення пустого буферу


callBinToAscDec ; заповнення буферу buffer10-ковим


; ASCII-представленням числа з ax


mov cx,2 ; в cxширина поля виводу


call StrWrite2 ; вивід ASCIIпредставлення номера дня


mov cx,1 ; в cxкількість виводів


mov dl, '\' ; в dlсимвол для виводу


callWriteSimv ; вивід символу із dlзадану кількість разів


; ------Вивід року створення файлу


movax,bx ; в axслово року створення файлу


andax,0f800h ; накладання маски


shrax,9 ; зсув результату (отримання року)


add ax,1980 ; отримання року створення


mov cx,1 ; встановлення мінімальної довжини


; перетворюваного рядка


movdi,offsetbuffer ; в diзміщення пустого буферу


callBinToAscDec ; заповнення буферу buffer10-ковим


; ASCII-представленням числа з ax


mov cx,4 ; в cxширина поля виводу


call StrWrite2 ; вивід ASCIIпредставлення номера дня


mov cx,2 ; в cxкількість виводів


mov dl, ' ' ; в dlсимвол для виведення


call WriteSimv ; вивід проміжку у 2-а пробіли


; ------Вивід розміру файлу у 16-річному вигляді


movax,[offsetdirData+ FileName-2] ; в axмолодші два байти


; подвійного слова розміру файла


mov cx,1 ; в cxмінімальна довжина


; перетворюваного рядка


mov di,offset buffer ; в diзміщення буферу для результату


call BinToAscHex ; перетворення двох молодших байтів


; розміну у ASCII-рядок


callStrWrite ; вивід на екран


movax,[offsetdirData+ FileName-4] в axмістяться старші два байти


; подвійного слова розміру файла


callBinToAscHex ; перетворення у ASCIIрядок


; представлення у вигляді 16-річного


; числа


callStrWrite ; вивід на екран


callNewLine ; перехід на новий рядок


pop bx ; відновлення у bxзміщення процедури


; Action


ret ; завершення процедури


ENDP Action


END Start


Схема алгоритму основної програми приведена у додатках (Додаток А).


Отримання даних із командного рядку і встановлення критерію відбору файлів (маски) реалізується за допомогою функцій модуля PARAMS.obj. Спочатку заповнюється спеціальний буфер хвостом команди і його вміст розбивається на окремі елементи (GetParams). При наявності в хвості команди параметрів, перший параметр задає маску; якщо параметри відсутні, у якості маски встановлюється стандартна '*.*'(вивід всіх файлів із директорії, в якій знаходиться програма). Основну роботу виконує функція DirEngine, в яку, за допомогою регістру bx, передається зміщення функції Action(для подальшого виклику її за зміщенням).


Функція DirEngine, за допомогою 2Fh, 1Ah, 4Eh, 4Fhфункцій переривання INT21hDOS, знаходить поточне положення буфера DTA, зберігає його адресу, встановлює новий DTAу власний спеціальний буфер і за допомогою нього шукає файли, що відповідають заданій масці. При знаходженні таких файлів, керування по зміщенню передається функції Action.


Основна задача Action– обробити інформацію в DTAі вивести необхідні дані на стандартний пристрій виводу.


DTA має наступну структуру [4, 6]:





























Зміщення Довжина
+0 15H Зарезервована, використовується функцією 4FhINT21hDOS
+15h 1 атрибут файла
+16h 2 час
+18h 2 дата
+1ah 4 розмір файла (формат DWORD)
+1eh 0dh 13-байтова ASCIIZім'я файлу

Спочатку виводиться ім'я файлу, яке має наступну структуру: "filename.ext". Вивід реалізується за допомогою спеціальних функцій StrWrite, StrWriter, Lengthі WriteSimvіз модуля STRIO.obj.


Наступним кроком реалізується вивід атрибутів файлу шляхом виводу зірочок навпроти відповідного атрибуту. Байт атрибуту файлу має наступну структуру[6]:























№ біту Що означає
0 тільки читання
1 скритий
2 системний
3 том
4 каталог
5 архів (або копія файлу не створювалась)

Тобто, якщо біт атрибуту файлу буде мати наступне значення 21h, це означатиме, що файл є архівним, він лише для читання.


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






































































№ біта Операція № біта Операція
Час створення Дата створення
15

година


(0-23)


(t & 0f800h)>>11 15

рік


(0-119)+1980


d & 001fh
14 14
13 13
12 12
11 11
10

хвилина


(0-59)


(t & 07e0h)>>5 10
9 9
8 8

місяць


(1-12)


(d & 01e0h)>>5
7 7
6 6
5 5
4

секунда / 2


(0-30)


t & 001fh 4

день


(0-31)


(d & f800h)>>9
3 3
2 2
1 1
0 0

отримання необхідної інформації і представлені в наступному виді [6]:


Перевід двійкових чисел у ASCII-десяткове представлення для виводу на екран реалізується за допомогою функції BinToAscDecмодуля BINASC.obj.


Останній крок виводу розміру файлу виконується в два етапи, оскільки розмір файлу міститься у подвійному слові і модуль BSNASC.objне надає інструменту для переведення двійкових даних у ASCII-рядок.


Спочатку за допомогою функції BinToAscHexмодуля BINASC.objпереводиться молодші, а потім старші два байти, переведені у ASCII-шістнадцятирічне представлення.


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


Результати роботи програми:


D:\Program\ASM\misk>dr


The DIRWUER wersion 1.0


Romanov Alexander Urievich. KIT-13A NTU"KhPI"


Copyright (C) 2005 by Romanov Alexander


Filename OnR Skr Sys Tom Kat Arh Time Data Size


. * 11:59:18 11\5 \2005 00


.. * 11:59:18 11\5 \2005 00


BLW32.DLL * 12:12:0 14\5 \1996 52020


DEBUG.EXE * * 22:22:0 5 \5 \1999 0518A


USA.BLL * 12:12:0 14\5 \1996 18DCD


MYREP.CBA * 18:48:42 25\1 \2002 01F


DIRECT * 12:27:54 11\5 \2005 00


CATALOG3.CAB * * 22:22:0 5 \5 \1999 425C3


SUHELPER.BIN * * 22:22:0 5 \5 \1999 05C0


SAVE32.COM * * 22:22:0 5 \5 \1999 0398


ASD.LOG * * 13:8 :20 11\8 \2004 0162


IO.SYS * * * 22:22:0 5 \5 \1999 364B6


MSDOS.SYS * * * * 18:30:28 16\7 \2004 0697


08-APRIL.MP3 * 11:42:44 7 \12\2003 B11100


DR.EXE * 12:14:28 11\5 \2005 05A1


DR.BAT * 12:54:34 4 \5 \2005 09B


D:\Program\ASM\misk>dr.exe *.exe


The DIRWUER wersion 1.0


Romanov Alexander Urievich. KIT-13A NTU"KhPI"


Copyright (C) 2005 by Romanov Alexander


Filename OnR Skr Sys Tom Kat Arh Time Data Size


DEBUG.EXE * * 22:22:0 5 \5 \1999 0518A


DR.EXE * 12:14:28 11\5 \2005 05A1


D:\Program\ASM\misk>dr s*.???


The DIRWUER wersion 1.0


Romanov Alexander Urievich. KIT-13A NTU"KhPI"


Copyright (C) 2005 by Romanov Alexander


Filename OnR Skr Sys Tom Kat Arh Time Data Size


SUHELPER.BIN * * 22:22:0 5 \5 \1999 05C0


SAVE32.COM * * 22:22:0 5 \5 \1999 0398


D:\Program\ASM\misk>dr d:\program\asm\misk\direct\*.*


The DIRWUER wersion 1.0


Romanov Alexander Urievich. KIT-13A NTU"KhPI"


Copyright (C) 2005 by Romanov Alexander


Filename OnR Skr Sys Tom Kat Arh Time Data Size


. * 12:27:54 11\5 \2005 00


.. * 12:27:54 11\5 \2005 00


BINASC.ASM * 11:3 :40 8 \5 \2005 0300


PARAMS.ASM * 13:31:20 6 \5 \2005 04E4


TD.EXE * 14:39:40 24\12\2002 784F0


Як видно із приведених результатів програма DR.EXEза умовчанням виводить весь вміст директорії, в якій вона розташована (приклад 1). Інші приклади демонструють різноманітні засоби виклику програми із заданням різноманітних масок, використовуючи символи "*" і "?". Останній приклад демонструє, що виклик DR.exeможна реалізувати і з маскою, що задає повний шлях до директорії, інформацію про яку необхідно вивести.


Таким чином, розроблена програма DR.exeповністю відповідає поставленому завданню про створення програми мовою асемблера, яка виводить вміст директорії, атрибути, розмір і час/дату створення файлів і папок, які в ній містяться.


4. Розробка задачі на мові високого рівня із використанням асемблерних фрагментів коду


Як показала третя глава, розробка програми чисто на асемблері є складним процесом і потребує розробки супутніх (допоміжних) модулів для реалізації моментів, що не пов’язані із основним алгоритмом задачі (таких, як вивід на екран, перетворення двійкових даних у ASCII-рядки, тощо). Мови високого рівня дають можливість реалізувати все автоматично [3]. Такий стан речей спонукає розробити програму, в якій основний алгоритм пошуку DTAі необхідних файлів, що відповідають масці, реалізовані асемблерними вставками, а задачі, пов’язані із розробкою інтерфейсу і виводу даних на екран, реалізовані, наприклад, мовою Pascal.


4.1. Розробка програми на
Pascal


Мова Pascalдає можливість створити вказівник типу "запис" (поля "запису" описують атрибут, час, дату, розмір і ім'я файлу) прямо на стандартний буфер DTA, не створюючи власного і не виконуючи зайвих дій по встановленню нової адреси буфера DTAі відновлення старої після завершення програми. Вивід інформації про файл довіряється процедурі, яка обробляє поля вказівника на DTAі виводить дані стандартними функціями Pascal.


На початку програми є сенс запитувати користувача про бажання задати власну маску для файлів, або лишити стандартну ("*.*").


Згідно із зазначеними змінами було розроблено програму DIRWUER.pas, приведену нижче:


{DIRWUER.pas}


Usescrt;


{------FindFirst – шукає перше входження файлу, що відповідає заданій масці}


Function FindFirst (Path : PChar) : Boolean; assembler;


asm


mov ah, 4Eh{в ahномер функції першого пошуку}


mov cx, 3fh{в cxмаска для всіх атрибутів файлу}


mov dx, word ptr Path{dxвказує на маску файлу}


int 21h{виклик функції першого пошуку файлу}


mov al, 0{в alпоміщується 0 – код помилки(false)}


jc @Failed {якщо помилка, повернути код помилки,}


inc al{інакше повернути 1 – true}


@Failed:


end;


{------FindNextшукає наступне входження файлів, маска і атрибути яких були задані при попередньому пошуку.}


FunctionFindNext: Boolean; assembler;


asm


movah, 4Fh{в ahномер функції наступного пошуку }


{файлу}


int 21h{пошук наступного файлу за параметром,}


{заданим функцією 4Eh}


moval, 0 {в alпоміщується 0 – код помилки (false)}


jc @Failed {повернути код помилки, якщо помилка}


inc al {інакше повернути 1 – true}


@Failed:


end;


Type


DTA = record{запис описує структуру DTA-буфера}


Reserved : Array[0..$14] of Byte;{резервна область пам'яті}


Attrib : Byte;{поле атрибуту}


Time : Word; {поле часу створення}


Date : Word; {поле дати}


Size : Longint;{розмір}


Name : Array[0..$C] of Char;{ім'я файлу із розширенням}


end;


PDTA= ^DTA; {вказівник на буфер DTA}


{------GetDTAAddressповертає адресу буфера DTA}


FunctionGetDTAAddress: PDTA; assembler;


asm


movah, 2Fh {в ahномер функції пошуку DTA}


int21h {отримання в as:bxадреси DTA}


pushes {в dxчерез стек передаються дані із es}


popdx


movax, bx {передача в axданих із bx}


{в dx:axповертається результат}


end;


Var


DTAAddress : PDTA;


s : string;


Path : PChar;


i : byte;


Label 1;


{------Процедура виводу даних о файлі/директорії згідно із інформацією в DTA}


Procedure ShowEntry;


Begin


Write(DTAAddress^.Name:13,' ');{вивід імені файлу із розширенням}


for i:= 0 to 5 do


if (DTAAddress^.Attrib and (1 shl i)) <>0


then write(' * ') {вивід зірочок навпроти файлів }


else write(' '); {із відповідними атрибутами}


{------Вивід часу створення файлу}


Write(' ',((DTAAddress^.Time and $0f800)shr 11):2);


Write(':',((DTAAddress^.Time and $07e0)shr 5):2,':');


Write(((DTAAddress^.Time and $1f)shl 1):2);


{------Вивід дати створення файлу}


Write(' ',(DTAAddress^.Date and $1f):2,'/');


Write(((DTAAddress^.Date and $01e0)shr5):2,'/');


Write((((DTAAddress^.Dateand$0f800)shr9)+$07bc):4);


Writeln(' ',DTAAddress^.Size:7); {вивід розміру файлу}


end;


BEGIN


ClrScr; {очистка екрану}


{------Вивід інформації о програмі}


Writeln('The DIRWUER wersion 1.0');


Writeln('Romanov Alexander Urievich. KIT-13A KHPI');


Writeln('Copyright (C) 2005 by Romanov Alexander');


DTAAddress := GetDTAAddress;{встановлення вказівника}


{на адресу DTA}


1:


Write('Input the mask (default: *.*; exit: q): '); {запит на введення маски}


Readln(s); {отримання відповіді}


if s='' then Path:='*.*'{якщо відповіді не має,}


{встановлення стандартної маски}


else if s='q' then halt {якщо відповідь 'q', завершення}


{роботи програми}


else Path:=Addr(s[1]); {встановлення заданої маски}


if FindFirst (Path)then {знаходження першого файлу}


begin


Write('Filename OnR Skr Sys Tom ');


Writeln('Kat Arh TimeDataSize'); {вивід заголовка таблиці}


ShowEntry; {вивід на екран даних про файл}


while FindNext do ShowEntry;{доки знайдено наступний файл,}


{виводити дані про нього на екран}


end


elsewriteln('Failed');{інакше, при незнаходженні}


{жодного файлу, виводиться}


{повідомлення про їх відсутність}


goto 1; {перехід на початок}


END.


Схема алгоритму програми приведена в додатках (Додаток Б).


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


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


Результати роботи програми проілюструємо наступним чином:


The DIRWUER wersion 1.0


Romanov Alexander Urievich. KIT-13A KHPI


Copyright (C) 2005 by Romanov Alexander


Input the mask (default: *.*; exit: q):


Filename OnR Skr Sys Tom Kat Arh Time Data Razmer


. * 11:59:18 11/5 /2005 00


.. * 11:59:18 11/5 /2005 00


BLW32.DLL * 12:12:0 14/5 /1996 52020


DEBUG.EXE * * 22:22:0 5 /5 /1999 0518A


USA.BLL * 12:12:0 14/5 /1996 18DCD


MYREP.CBA * 18:48:42 25/1 /2002 01F


DIRECT * 12:27:54 11/5 /2005 00


CATALOG3.CAB * * 22:22:0 5 /5 /1999 425C3


SUHELPER.BIN * * 22:22:0 5 /5 /1999 05C0


SAVE32.COM * * 22:22:0 5 /5 /1999 0398


ASD.LOG * * 13:8 :20 11/8 /2004 0162


IO.SYS * * * 22:22:0 5 /5 /1999 364B6


MSDOS.SYS * * * * 18:30:28 16/7 /2004 0697


08-APRIL.MP3 * 11:42:44 7 /12/2003 B11100


DR.EXE * 12:14:28 11/5 /2005 05A1


DR.BAT * 12:54:34 4 /5 /2005 09B


DIRWUER.EXE * 13:48:38 13/ 5/2005 6256


Input the mask (default: *.*; exit: q): *.b??


Filename OnR Skr Sys Tom Kat Arh Time Data Razmer


USA.BLL * 12:12: 0 14/ 5/1996 101837


SUHELPER.BIN * * 22:22: 0 5/ 5/1999 1472


DR.BAT * 12:54:34 4/ 5/2005 155


Input the mask (default: *.*; exit: q): direct/*.*


Filename OnR Skr Sys Tom Kat Arh Time Data Razmer


. * 12:27:54 11/ 5/2005 0


.. * 12:27:54 11/ 5/2005 0


BINASC.ASM * 11: 3:40 8/ 5/2005 768


PARAMS.ASM * 13:31:20 6/ 5/2005 1252


TD.EXE * 14:39:40 24/12/2002 492784


Input the mask (default: *.*; exit: q): q


Аналізуючи отримані результати, зазначимо, що за умовчанням (перший приклад) програма DIRWUER.exeвиводить увесь вміст директорії, в якій вона розташована. Інші приклади демонструють різноманітні засоби задання масок файлів із використанням символів "*" і "?", а також задання шляху до директорії, вміст якої необхідно вивести. Відповідь "q" завершує програму.


Таким чином DIRWUER.exeє повноцінною програмою, яка реалізує вивід інформації о файлах, що відповідають заданій масці. Відмінність програми DIRWUER.exeвід DR.exeполягає в покращеному інтерфейсі і більш ефективній роботі із буфером DTA, що стало можливим при використанні мови високого рівня Pascal, як оболонки при написанні програми.


Висновки


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


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


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


Список використаних джерел


1. Методические указания к лабораторным работам № 10–№ 18 по курсу "Архитектура вычислительных систем" / Составит. А.И. Поворознюк, И.С. Зыков. – Харьков: ХПИ. – 88 с.


2. Поворознюк А.И. Архитектура компьютеров. Архитектура микропроцессорного ядра и системных устройств: Учеб. пособие. Ч.2. – Харьков: Торнадо, 2004. – 355 с.


3. ПустоваровВ.И. Язык Ассемблера в программировании информационных и управляющих систем. – М.: ЭНТРОП, 1997. – 304 с.


4. Сван Т. Освоение TurboAssembler. – К.: Диалектика, 1996. – 544 с.


5. Белецкий Я. Турбо Ассемблер: Версия 2.0: Учеб. пособие для студентов вузов / Пер. с польск. В.В. Яценко. М.: Машиностроение, 1994. – 160 с.


6. RollinsD. TECHHelp. Электронный справочник. Версия 1.2. / Адапт. С.М. Абель. – FlambeauxSoftware. –© 1985–1987.


7. Norton P. Peter Norton's DOS Guide. – New Delhi: Prentice Hall of India Private Limited, 1996. – 744 p.


Додатки


Додаток А


Схема алгоритму DR.asm




Додаток Б


Схема алгоритму DIRWUER.pas





Схема алгоритму
D
I
RWUER
.
pas
(продовження)




Не сдавайте скачаную работу преподавателю!
Данную дипломную работу Вы можете использовать как базу для самостоятельного написания выпускного проекта.

Поделись с друзьями, за репост + 100 мильонов к студенческой карме :

Пишем дипломную работу самостоятельно:
! Как писать дипломную работу Инструкция и советы по написанию качественной дипломной работы.
! Структура дипломной работы Сколько глав должно быть в работе, что должен содержать каждый из разделов.
! Оформление дипломных работ Требования к оформлению дипломных работ по ГОСТ. Основные методические указания.
! Источники для написания Что можно использовать в качестве источника для дипломной работы, а от чего лучше отказаться.
! Скачивание бесплатных работ Подводные камни и проблемы возникающие при сдаче бесплатно скачанной и не переработанной работы.
! Особенности дипломных проектов Чем отличается дипломный проект от дипломной работы. Описание особенностей.

Особенности дипломных работ:
по экономике Для студентов экономических специальностей.
по праву Для студентов юридических специальностей.
по педагогике Для студентов педагогических специальностей.
по психологии Для студентов специальностей связанных с психологией.
технических дипломов Для студентов технических специальностей.

Виды дипломных работ:
выпускная работа бакалавра Требование к выпускной работе бакалавра. Как правило сдается на 4 курсе института.
магистерская диссертация Требования к магистерским диссертациям. Как правило сдается на 5,6 курсе обучения.

Другие популярные дипломные работы:

Дипломная работа Формирование устных вычислительных навыков пятиклассников при изучении темы "Десятичные дроби"
Дипломная работа Технологии работы социального педагога с многодетной семьей
Дипломная работа Человеко-машинный интерфейс, разработка эргономичного интерфейса
Дипломная работа Организация туристско-экскурсионной деятельности на т/к "Русский стиль" Солонешенского района Алтайского края
Дипломная работа Разработка мероприятий по повышению эффективности коммерческой деятельности предприятия
Дипломная работа Совершенствование системы аттестации персонала предприятия на примере офиса продаж ОАО "МТС"
Дипломная работа Разработка системы менеджмента качества на предприятии
Дипломная работа Организация учета и контроля на предприятиях жилищно-коммунального хозяйства
Дипломная работа ЭКСПРЕСС-АНАЛИЗ ФИНАНСОВОГО СОСТОЯНИЯ ООО «АКТ «ФАРТОВ»
Дипломная работа Психическая коммуникация

Сейчас смотрят :

Дипломная работа Недвижимость как объект гражданских прав
Дипломная работа Организационно-технологическое обеспечение анимационных программ в молодежном туризме
Дипломная работа Информатика и информационные технологии в образовании
Дипломная работа Проектирование электрической подстанции
Дипломная работа Инновации в сфере управления персоналом на примере ООО "Евросеть Санкт-Петербург"
Дипломная работа Технология получения лекарственных пленок для лечения термических ожогов
Дипломная работа Гражданско-правовые отношения
Дипломная работа Резервы повышения эффективности производства в столярном цехе ООО "Сакура"
Дипломная работа Развитие художественно-творческих способностей детей 5-6-летнего возраста
Дипломная работа Нравственное воспитание младших школьников в учебно-воспитательном процессе
Дипломная работа Банковское кредитование юридических лиц: пути оптимизации
Дипломная работа Договор поставки товаров для государственных и муниципальных нужд
Дипломная работа Перевезення цементу автомобільним транспортом ЗАТ "УБ РАЕС"
Дипломная работа Разработка бизнес-плана предприятия
Дипломная работа Процес виробництва, виходу продукції соняшнику та визначення її собівартості у СГ ТОВ "Хлібопродукт"