Смекни!
smekni.com

Вивід вмісту каталогу y середовищі MS DOS (стр. 3 из 6)

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 ; отримати параметри із командного рядка