Чтобы использовать целочисленную арифметику, умножим tg и
EPS на (X2-X1)*2 : TG = (Y2 - Y1) а условие приращения Y: EPS > (X2 - X1) Итак, теперь TG=(y2-y1)*2; EPS=0; lamb=(x2-x1)*2; y=y1; for (x=x1; x<=x2; x++) { pixel(x,y); EPS+=TG if(EPS>(x2-x1)){y++;EPS-=lamb} } Assume CS: Code;, DS: Code Code SEGMENT org 100h Start: jmp start1 color db 0 ; Текущий цвет x1 dw 0 ; Координата Х1 y1 dw 0 ; Координата У1 x2 dw 0 ; Координата Х2 y2 dw 0 ; Координата У2 lamb dw 0 ; Коэффициент лямбда tg dw 0 ; Наклон прямой start1: ; Установка видеорежима mov ah,0 ; Функция установки видеорежима mov al,4 ; Граф. реж. CGA 320 * 200 точек int 10h ; Построение линии X1,Y1 - X2,Y2 mov color,3 ; Цвет белый mov x1,20 mov y1,15 mov x2,300 mov y2,60 call line call kbin int 20h ; Построение линии ; X1,Y1 - координаты начала линии ; X2,Y2 - координаты конца линии line proc near mov ax,x2 sub ax,x1 ; X2 - X1 mov si,ax ; SI = X2-X1 shl ax,1 ; * 2 mov lamb,ax ; Лямбда в переменную mov ax,y2 sub ax,y1 ; Y2 - Y1 shl ax,1 ; * 2 mov tg,ax ; Наклон в переменную xor bp,bp ; Погрешность mov dx,y1 mov cx,x1 line1: call pixel add bp,tg cmp si,bp ; (X2-X1) : D jge line2 ; D <= (X2-X1) ; D > (X2-X1) inc dx ; Y=Y+1 sub bp,lamb ; D=D-lamb line2: inc cx cmp cx,x2 jnz line1 ret line endp ; Ввод с клавиатуры kbin proc near mov ah,0 ; Функция 0 int 16h ; клавиатурного прерывания ret kbin endp ; Построение точки текущего цвета ; CX - координата Х ; DX - координата Y pixel proc near push bx mov al,color mov ah,0ch ; Функция построения графич. точки mov bh,0 ; Видеостраница int 10h pop bx ret pixel endp code ends END Start ; Указание точки входа в программу Написать программу, рисующую прямую линию с произвольным наклоном. Для этого надо: · определить, какая переменная X или Y является независимой · определить знак приращения X и Y Assume CS: Code;, DS: Code Code SEGMENT org 100h Start: jmp start1 color db 0 ; Текущий цвет x1 dw 0 ; Координата Х1 y1 dw 0 ; Координата У1 x2 dw 0 ; Координата Х2 y2 dw 0 ; Координата У2 x_inc dw 0 ; Приращение Х y_inc dw 0 ; Приращение Y ddy dw 0 ; Y2 - Y1 ddx dw 0 ; X2 - X1 lamb dw 0 ; Коэффициент лямбда tg dw 0 ; Наклон прямой start1: ; Установка видеорежима mov ah,0 ; Функция установки видеорежима mov al,4 ; Граф. реж. CGA 320 * 200 точек int 10h ; Построение линии X1,Y1 - X2,Y2 mov color,3 ; Цвет белый mov x1,160 mov y1,100 mov x2,60 mov y2,10 call line call kbin int 20h ; Построение линии ; X1,Y1 - координаты начала линии ; X2,Y2 - координаты конца линии line proc near ; Определение знака приращения Y mov ax,y2 cmp ax,y1 jnc line01 ; y1 <= y2 ; y2 < y1 - отрицательное приращение mov y_inc,-1 mov bx,y1 sub bx,ax ; Y1 - Y2 mov ddy,bx ; abs(Y2-Y1) jmp line02 line01: mov y_inc,1 ; Положительное приращение sub ax,y1 ; Y2 - Y1 mov ddy,ax ; abs(Y2-Y1) ; Определение знака приращения X line02: mov ax,x2 cmp ax,x1 jnc line03 ; x1 <= x2 ; x2 < x1 - отрицательное приращение mov x_inc,-1 mov bx,x1 sub bx,ax ; X1 - X2 mov ddx,bx ; abs(X2-X1) jmp line04 line03: mov x_inc,1 ; Положительное приращение sub ax,x1 ; X2 - X1 mov ddx,ax ; abs(X2-X1) ; Определение независимой переменной line04: mov ax,ddx cmp ax,ddy jnc line1 ; (Y2-Y1) < (X2-X1) jmp line2 ; (Y2-Y1) > (X2-X1) ; Построение при (Y2-Y1) < (X2-X1) line1: mov ax,ddx ; ax = X2-X1 mov si,ddx ; SI = X2-X1 shl ax,1 ; * 2 mov lamb,ax ; Лямбда в переменную mov ax,ddy shl ax,1 ; * 2 mov tg,ax ; Наклон в переменную xor bp,bp ; Погрешность mov dx,y1 mov cx,x1 line11: call pixel add bp,tg cmp si,bp ; (X2-X1) : D jge line12 ; D <= (X2-X1) ; D > (X2-X1) add dx,y_inc ; Y=Y+1 sub bp,lamb ; D=D-lamb line12: add cx,x_inc cmp cx,x2 jnz line11 ret ; Построение при (Y2-Y1) > (X2-X1) line2: mov ax,ddy ;ax = Y2 - Y1 mov si,ax ; SI = Y2 - Y1 shl ax,1 ; * 2 mov lamb,ax ; Лямбда в переменную mov ax,ddx shl ax,1 ; * 2 mov tg,ax ; Наклон в переменную xor bp,bp ; Погрешность mov dx,y1 mov cx,x1 line21: call pixel add bp,tg cmp si,bp ; (Y2-Y1) : D jge line22 ; D <= (Y2-Y1) ; D > (X2-X1) add cx,x_inc sub bp,lamb ; D=D-lamb line22: add dx, y_inc cmp dx,y2 jnz line21 ret line endp ; Ввод с клавиатуры kbin proc near mov ah,0 ; Функция 0 int 16h ; клавиатурного прерывания ret kbin endp ; Построение точки текущего цвета ; CX - координата Х ; DX - координата Y pixel proc near push bx mov al,color mov ah,0ch ; Функция построения графич. точки mov bh,0 ; Видеостраница int 10h pop bx ret pixel endp code ends END Start ; Указание точки входа в программу
2.1.4. Вывод динамических изображений
Написать программу, которая в графическом режиме CGA 4 * 320 * 200 рисует фигурку колобка размером 16 * 16 точек непосредственно в экранной области и перемещает его при нажатии курсорных клавиш. Коды управления курсором: Вверх - 48h, Вниз - 50h, Вправо - 4Dh, Влево - 4Bh. Структура видеопамяти в режиме CGA: начинается с адреса B000h, четные линии имеют смещение 0000h - 1F3Fh (около 8 КВ), нечетные 2000h - 3F3Fh (около 8 КВ) (промежуток между ними не используется).
Цвет 00 - черный 01 - голубой (зеленый) 10 - сиреневый (красный) 11 - белый (желтый) Assume CS: Code;, DS: Code Code SEGMENT org 100h Start: jmp start1 addr dw 0 ; Адрес начальной точки спрайта addr0 dw 0 ; Старый адрес ; 16 * 16 colob db 0,5,50h,0 db 0,5fh,0f5h,0 db 5,0ffh,0ffh,50h db 3fh,0ffh,0ffh,0fch db 0ffh,0afh,0fah,0ffh db 0ffh,0abh,0eah,0ffh db 0ffh,8bh,0e2h,0ffh db 0ffh,0ffh,0ffh,0ffh db 3fh,0beh,0beh,0fch db 0fh,0efh,0fbh,0f0h db 0,0fah,0afh,0 db 0,3fh,0fch,0 db 0,3ch,3ch,0 db 15h,3ch,3ch,54h db 55h,54h,15h,55h db 55h,54h,15h,55h start1: ; Установка видеорежима mov ah,0 ; Функция установки видеорежима mov al,4 ; Граф. реж. CGA 320 * 200 точек int 10h mov di,addr st2: lea si,colob call sprit0 call sprite ; Сохранение исходных координат mov ax,addr mov addr0,ax ; Чтение клавиатуры call kbin cmp ah,1 ; Скан-код = Esc ? jnz st3 ; Нет int 20h ; Выход при нажатии Esc st3: cmp ah,48h ; Вверх ? jnz st4 sub addr,80*2 ; Вверх на 4 строки jmp st2 st4: cmp ah,50h ; Вниз ? jnz st5 add addr,80*2 ; Вниз на 4 строки jmp st2 st5: cmp ah,4dh ; Вправо ? jnz st6 inc addr jmp st2 st6: cmp ah,4bh ; Влево ? jnz st2 dec addr jmp st2 ; Ввод с клавиатуры kbin proc near mov ah,0 ; Функция 0 int 16h ; клавиатурного прерывания ret kbin endp ; Построение спрайта 16 * 16 ; addr - адрес левого верхнего угла ; SI - начало спрайта sprite proc near ; Построение четных строк push si mov di,addr mov ax,0b800h mov es,ax mov bp,8 ; Счетчик числа строк/2 sp1: mov cx,4 ; Счетчик числа слов rep movsb add di,76 add si,4 dec bp jnz sp1 ; Построение нечетных строк mov di,addr pop si add si,4 ; Переход к нечетной строке mov ax,0ba00h mov es,ax mov bp,8 ; Счетчик числа строк/2 sp2: mov cx,4 ; Счетчик числа слов rep movsb add di,76 add si,4 dec bp jnz sp2 ret sprite endp ; Стирание спрайта 16 * 16 ; addr0 - координаты левого верхнего угла sprit0 proc near ; Стирание четных строк mov di,addr0 mov ax,0b800h mov es,ax mov bp,8 ; Счетчик числа строк/2 xor al,al sp3: mov cx,4 ; Счетчик числа слов rep stosb add di,76 dec bp jnz sp3 ; Стирание нечетных строк mov di,addr0 mov ax,0ba00h mov es,ax mov bp,8 ; Счетчик числа строк/2 sp4: mov cx,4 ; Счетчик числа слов rep stosb add di,76 dec bp jnz sp4 ret sprit0 endp code ends END Start ; Указание точки входа в программу
Изменить палитру на красный-зеленый-желтый. При движении менять проекции фигурки. Палитра переключается в режиме 4: int 10h, функция 0Bh BH=1, BL=палитра (0, 1) Assume CS: Code;, DS: Code Code SEGMENT org 100h Start: jmp start1 addr dw 0 ; Адрес начальной точки спрайта addr0 dw 0 ; Старый адрес ; 16 * 16 colf db 0,5,50h,0 db 0,5fh,0f5h,0 db 5,0ffh,0ffh,50h db 3fh,0ffh,0ffh,0fch db 0ffh,0afh,0fah,0ffh db 0ffh,0abh,0eah,0ffh db 0ffh,8bh,0e2h,0ffh db 0ffh,0ffh,0ffh,0ffh db 3fh,0beh,0beh,0fch db 0fh,0efh,0fbh,0f0h db 0,0fah,0afh,0 db 0,3fh,0fch,0 db 0,3ch,3ch,0 db 15h,3ch,3ch,54h db 55h,54h,15h,55h db 55h,54h,15h,55h colb db 0,5,50h,0 db 0,55h,55h,0 db 5,55h,55h,50h db 15h,55h,55h,54h db 0d5h,55h,55h,57h db 0d5h,55h,55h,57h db 0f5h,55h,55h,5fh db 0fdh,55h,55h,7fh db 3dh,55h,55h,7ch db 0fh,55h,55h,0f0h db 0,0ffh,0ffh,0 db 0,3fh,0fch,0 db 0,3ch,3ch,0 db 15h,3ch,3ch,54h db 55h,54h,15h,55h db 55h,54h,15h,55h coll db 0,5,50h,0 db 0,5fh,55h,50h db 5,7fh,55h,50h db 1,0ffh,0fdh,54h db 2,0ffh,0ffh,55h db 2,0bfh,0ffh,55h db 0fch,0bfh,0ffh,0d5h db 0ffh,0ffh,0ffh,0f5h db 0fh,0ffh,0bfh,0fch db 3,0feh,0ffh,0f0h db 0,0abh,0ffh,0 db 0,3fh,0fch,0 db 0,0fh,0fch,0 db 15h,0fh,0fch,0 db 55h,55h,55h,0 db 55h,55h,55h,0 colr db 0,5,50h,0 db 0,55h,0f5h,0 db 5,55h,0fdh,50h db 15h,7fh,0ffh,40h db 55h,0ffh,0ffh,80h db 55h,0ffh,0feh,80h db 57h,0ffh,0feh,3fh db 3fh,0ffh,0ffh,0ffh db 3fh,0feh,0ffh,0f0h db 0fh,0ffh,0bfh,0c0h db 0,0ffh,0eah,0 db 0,3fh,0fch,0 db 0,3fh,0f0h,0 db 0,3fh,0f0h,54h db 0,55h,55h,55h db 0,55h,55h,55h start1: ; Установка видеорежима mov ah,0 ; Функция установки видеорежима mov al,5 ; Граф. реж. CGA 320 * 200 точек int 10h mov ah,0bh ; Установка палитры mov bx,102h int 10h mov di,addr lea si,colf st2: call sprit0 call sprite ; Сохранение исходных координат st0: mov ax,addr mov addr0,ax ; Чтение клавиатуры call kbin cmp ah,1 ; Скан-код = Esc ? jnz st3 ; Нет int 20h ; Выход при нажатии Esc st3: cmp ah,48h ; Вверх ? jnz st4 sub addr,80*2 ; Вверх на 4 строки lea si,colb jmp st2 st4: cmp ah,50h ; Вниз ? jnz st5 add addr,80*2 ; Вниз на 4 строки lea si,colf jmp st2 st5: cmp ah,4dh ; Вправо ? jnz st6 inc addr lea si,colr jmp st2 st6: cmp ah,4bh ; Влево ? jnz st0 dec addr lea si,coll jmp st2 ; Ввод с клавиатуры kbin proc near mov ah,0 ; Функция 0 int 16h ; клавиатурного прерывания ret kbin endp ; Построение спрайта 16 * 16 ; addr - адрес левого верхнего угла ; SI - начало спрайта sprite proc near ; Построение четных строк push si mov di,addr mov ax,0b800h mov es,ax mov bp,8 ; Счетчик числа строк/2 sp1: mov cx,4 ; Счетчик числа слов rep movsb add di,76 add si,4 dec bp jnz sp1 ; Построение нечетных строк mov di,addr pop si add si,4 ; Переход к нечетной строке mov ax,0ba00h mov es,ax mov bp,8 ; Счетчик числа строк/2 sp2: mov cx,4 ; Счетчик числа слов rep movsb add di,76 add si,4 dec bp jnz sp2 ret sprite endp ; Стирание спрайта 16 * 16 ; addr0 - координаты левого верхнего угла sprit0 proc near ; Стирание четных строк mov di,addr0 mov ax,0b800h mov es,ax mov bp,8 ; Счетчик числа строк/2 xor al,al sp3: mov cx,4 ; Счетчик числа слов rep stosb add di,76 dec bp jnz sp3 ; Стирание нечетных строк mov di,addr0 mov ax,0ba00h mov es,ax mov bp,8 ; Счетчик числа строк/2 sp4: mov cx,4 ; Счетчик числа слов rep stosb add di,76 dec bp jnz sp4 ret sprit0 endp code ends END Start ; Указание точки входа в программу
РАБОТА С ДИСКАМИ
2.2.1. Работа с гибкими дисками
Написать программу, которая записывает 6-байтовый пароль на 40 дорожку ключевой дискеты.записано то, что надо. Assume CS: Code;, DS: Code Code SEGMENT org 100h disk equ 0 ; Диск А golovka equ 0 ; Гловка 0 dorojka equ 40 ; Дорожка 10 sector_track equ 15 ; Секторов на дорожке sector equ 15 ; Номер сектора .286 Start: jmp start1 Buffer db 'ququ',251 dup (?) db '1$' buffer_format db 40,0,1,1 ; Дор., гол., сект., код сект db 40,0,2,1 db 40,0,3,1 db 40,0,4,1 db 40,0,5,1 db 40,0,6,1 db 40,0,7,1 db 40,0,8,1 db 40,0,9,1 db 40,0,10,1 db 40,0,11,1 db 40,0,12,1 db 40,0,13,1 db 40,0,14,1 db 40,0,15,1 err_set db 0dh,0ah,0ah,'Ошибка установки типа дискеты',0dh,0ah,'$' err_read db 0dh,0ah,0ah,'Ошибка чтения с диска ','$' tabl_par dw 0,0 ; Адрес таблицы параметров дискеты start1: mov ax,cs mov ds,ax ; Установка типа дискеты mov ah,17h mov al,2 ; Дискета 360 КВ в дисководе 1,2 М mov dl,0 int 13h jnc m1 ; Сообщение об ошибке установки типа дискеты mov ah,09 lea dx,err_set int 21h call rest int 20h ; Считыание и сохранение адреса таблицы параметров ; дискеты (находится на месте вектора прерывания 1Eh) m1: mov ah,35h mov al,1Eh int 21h mov tabl_par,bx ; Смещение mov tabl_par+2,es ; Сегмент mov byte ptr es:[bx+3],1 ; Код размера сектора (256) mov byte ptr es:[bx+4],sector_track ; Количество секторов push cs pop es ; Чтение текста из сектора mov ah,2 ; Функция чтения сектора mov al,1 ; Количество секторов mov ch,dorojka ; Цилиндр mov cl,sector ; Сектор mov dh,golovka ; Головка mov dl,disk ; Диск lea bx,buffer ; Читаемый текст int 13h jnc m3 ; Сообщение об ошибке чтения mov ah,09 lea dx,err_read int 21h jmp m4 m3: mov ah,09 lea dx,buffer int 21h m4: call rest int 20h rest proc near ; Восстановление таблицы параметров дискеты ; (находится на месте вектора прерывания 1Eh) mov ah,35h ; Взятие вектора mov al,1Eh ; Номер вектора int 21h mov byte ptr es:[bx+3],2 ; Код размера сектора (512) mov byte ptr es:[bx+4],9 ; Количество секторов ret rest endp Code ENDS END Start
Написать программу, которая проверяет наличие пароля на 40 дорожке ключевой дискеты и выводит сообщение: · "Все в порядке", - если пароль верен, · "Вставьте ключевую дискету" - в любом другом случае. Assume CS: Code;, DS: Code Code SEGMENT org 100h disk equ 0 ; Диск А golovka equ 0 ; Гловка 0 dorojka equ 40 ; Дорожка 10 sector_track equ 15 ; Секторов на дорожке sector equ 15 ; Номер сектора .286 Start: jmp start1 Buffer db 'ququ',251 dup(?) db '1$' err_1 db 24 dup (0ah),0dh db 26 dup (32),'Установите ключевую дискету!' db 12 dup (0ah),'$' msg_ok db 24 dup (0ah),0dh db 30 dup (32),'Все в порядке' db 12 dup (0ah),'$' password db 'Пароль' ; Пароль, который будет распознаваться tabl_par dw 0,0 ; Адрес таблицы параметров дискеты start1: mov ax,cs mov ds,ax ; Установка типа дискеты mov ah,17h ; Функция определения типа дискеты mov al,2 ; Дискета 360 КВ в дисководе 1,2 М mov dl,0 ; Дисковод А int 13h jc err1 ; Переход на сообщение об ошибке ; Считыание и сохранение адреса таблицы параметров ; дискеты (находится на месте вектора прерывания 1Eh) mov ah,35h mov al,1Eh int 21h mov tabl_par,bx ; Смещение mov tabl_par+2,es ; Сегмент mov byte ptr es:[bx+3],1 ; Код размера сектора (256) mov byte ptr es:[bx+4],sector_track ; Количество секторов push cs pop es ; Чтение текста из сектора mov ah,2 ; Функция чтения сектора mov al,1 ; Количество секторов mov ch,dorojka ; Цилиндр mov cl,sector ; Сектор mov dh,golovka ; Головка mov dl,disk ; Диск lea bx,buffer ; Читаемый текст int 13h jc err1 ; Проверка пароля mov cx,6 ; Количество байтов в пароле lea si,buffer+10 ; Позиция, с которой записан пароль lea di,password ; Смещение пароля m1: lodsb ; [si]->al cmp al,[di] ; Сравнение с байтом пароля jnz err1 ; Переход на сообщение об ошибке inc di ; Переход к следующему символу в пароле ; inc si не нужен, так как он автоматически ; выполняется в команде lodsb loop m1 ; Переход на начало цикла проверки пароля ; Все в порядке mov ah,09 ; Функция вывода строки lea dx,msg_ok ; Сообщение 'Все в порядке' int 21h ; Вызов функции DOS ; Ожидание нажатия клавиши mov ah,0 ; Функция 0 int 16h ; Клавиатурное прерывание call rest ; Восстановление табл. парам. дискеты int 20h ; Выход из программы ; Сообщение об ошибке err1: mov ah,09 ; Функция 0 lea dx,err_1 ; Сообщение об ошибке int 21h ; Вызов функции DOS ; Ожидание нажатия клавиши mov ah,0 ; Функция 0 int 16h ; Клавиатурное прерывание call rest ; Восстановление табл. парам. дискеты int 20h ; Выход из программы rest proc near ; Восстановление таблицы параметров дискеты ; (находится на месте вектора прерывания 1Eh) mov ah,35h ; Взятие вектора mov al,1Eh ; Номер вектора int 21h mov byte ptr es:[bx+3],2 ; Код размера сектора (512) mov byte ptr es:[bx+4],9 ; Количество секторов ; Сброс диска 0 xor ax,ax ; Функция 0 xor dl,dl ; Дисковод А int 21h ; Вызов функции DOS ret rest endp Code ENDS END Start
2.2.2. Работа с жестким диском
Написать программу, которая при первом запуске (инициализации) определяет начальный кластер своего расположения на диске, записывает в файл на диск этот номер и выполняет свою основную функцию - выводит сообщение на экран, что все в порядке. При повторном и последующих запусках программа должна проверять, соответствует ли записанный в ней при инициализации номер начального кластера действительному номеру. При совпадении программа должны выполнить свою основную функцию - вывести сообщение о том, что все в порядке. При несовпадении записанного в программе и действительного номеров начального кластера программа должна вывести на экран сообщение о нежелании работать. Assume CS: Code;, DS: Code Code SEGMENT bpb struc ; Структура блока параметров BIOS sect_siz dw ? ; Размер сектора в байтах clus_siz db ? ; Секторов в кластере res_sect dw ? ; Зарезервированных секторов fat_num db ? ; Кол-во FAT на диске root_siz dw ? ; Размер каталога (кол-во файлов) num_sect dw ? ; Общее количество секторов med_desc db ? ; Дескриптор носителя fat_siz dw ? ; Число секторов в FAT sec_trac dw ? ; Число секторов на дорожке num_had dw ? ; Число головок hidd_sec dw ? ; Число скрытых секторов bpb ends bpd struc ; Структура блока параметров диска sec_num dd ? ; 32-битный номер сектора number_s dw ? ; Количество читаемых секторов b_off dw ? ; Смещение буфера b_seg dw ? ; Сегмент буфера bpd ends cat struc ; Структура записи каталога f_name db 11 dup (?) ; Имя файла с расширением f_attr db ? ; Атрибуты res_dos db 10 dup (?) ; Резерв f_time dw ? ; Время создания f_date dw ? ; Дата создания b_clu dw ? ; Начальный кластер f_size dd ? ; Размер файла cat ends .286 org 100h Start: jmp st1 key dw ? ; Начальный кластер f_key db 0 ; Флаг инициализации err_read db 'Ошибка чтения $' ok db 12 dup(0ah),0dh,25 dup(' ') db 'Все в порядке',12 dup(0ah),'$' nok db 12 dup(0ah),0dh,25 dup(' ') db "I'm sorry",12 dup(0ah),'$' fil_name db 'LAB2.COM',0 f_num_s dw ? ; Физ. номер сектора sec_cyl dw ? ; Число секторов на цилиндре sec_cat db ? ; Секторов в корневом каталоге cyl db ? ; Цилиндр head db ? ; Головка beg_sec dd ? ; Нач. сектор раздела (логич.) num_sec dw ? ; Кол. читаемых сект. каталога point dw ? ; Указатель в тек. каталоге flag db ? ; Флаг поиска f_flag db ? ; Флаг поиска файла root_s dw ? ; Лог. ном. сект. нач. корн. кат. clu0 dw ? ; Лог. ном. первого доступн. кластера handler dw ? ; Дескриптор файла buf_cat db 100h dup(?),'$' ; Буфер для тек. каталога buf1 db 200h dup(?) ; Буфер для MBR buf2 db 200h dup(?) ; Буфер для BR db '$' buf3 db 800h dup(?) ; Буфер для корн.кат. db '$' b_param db 10 dup(0) ; Блок параметров для int 25h st1: mov ax,cs mov ds,ax ; Определение начального кластера lea ax,buf_cat ; Инициализация указателя на начало mov point,ax ; буфера текущего каталога ; Получение текущего каталога в buf_cat mov ah,47h ; Получение текущего каталога xor dl,dl ; Текущий дисковод lea si,buf_cat ; Буфер для ASCIIZ тек. каталога int 21h ; Тек' каталог в buf_cat jnc st2 ; Ошибки нет ; Ошибка чтения сектора lea dx,err_read mov al,1 ; Ошибка чтения 1 call msg int 20h st2: ; Чтение BR в buf2 mov al,2 ; Диск С mov cx,-1 ; Признак > 32 M lea bx,b_param ; Блок параметров mov word ptr [bx].sec_num,0 ; Отн. номер сектора mov word ptr [bx+2].sec_num,0 ; Отн. номер сектора mov [bx].number_s,1 ; Кол-во читаемых секторов mov [bx].b_off,offset buf2 mov dx,cs mov [bx].b_seg,dx int 25h ; BR в buf2 pop cx jnc st3 ; Ошибки нет ; Ошибка чтения сектора lea dx,err_read mov al,2 ; Второе чтение сектора call msg int 20h ; Чтение корневого каталога в buf3 st3: lea si,[buf2+11] ; Определение количества читаемых секторов каталога ; (один кластер, но не более 4) mov al,[si].clus_siz ; Размер кластера cmp al,4 ; Разм. кластера < 4 jc st31 mov al,4 st31: xor ah,ah mov num_sec,ax ; Кол-во читаемых секторов кат. ; Определение числа секторов в корневом каталоге mov ax,[si].root_siz ; Размер кат. (кол.файлов) mov cl,4 shr ax,cl ; /16 (записей в секторе) mov sec_cat,al ; Секторов в каталоге ; Определение физ. номера сектора начала корневого каталога mov dl,[si].fat_num ; Кол-во FAT на диске mov ax,[si].fat_siz ; Число секторов в FAT mul dl ; AX -номер сект. нач. корнев. кат. inc ax ; Лог. номер сектора нач. корн. кат. mov root_s,ax ; Лог. ном. сект. нач. корн. кат. lea bx,b_param ; Блок параметров mov word ptr [bx].sec_num,ax ; Отн. номер сект. mov word ptr [bx+2].sec_num,0 ; Отн. номер сект. mov al,2 ; Диск С mov cx,-1 ; Признак > 32 M mov di,num_sec mov [bx].number_s,di ; Кол-во читаемых секторов mov [bx].b_off,offset buf3 mov dx,cs mov [bx].b_seg,dx int 25h ; Каталог в buf3 pop cx jnc st4 ; Ошибки нет ; Ошибка чтения сектора lea dx,err_read mov al,3 call msg int 20h st4: ; Определение логического номера сектора первого ; доступного кластера на текущем логическом диске mov bp,root_s ; Лог.ном.сект.нач.корн.кат. mov bl,sec_cat xor bh,bh add bp,bx ; + сект. в корн. каталоге mov clu0,bp mov byte ptr f_flag,0 ; Ищется не файл ; Цикл поиска каталогов вплоть до текущего st40: mov cx,64 ; Кол. анализируемых записей lea si,buf3 ; Начало 1 записи каталога st41: cmp byte ptr [si],0 ; Пустая запись ? jz st42 ; Пропуск cmp byte ptr [si],0e5h ; Стертая запись ? jz st42 ; Пропуск call comp ; Сравнение с искомым cmp flag,1 ; Hайден ? jz st43 ; Найден st42: add si,32 ; Переход к следующей записи loop st41 ; Ошибка поиска lea dx,err_read mov al,4 call msg int 20h st43: test byte ptr [di],0ffh ; Конец имени каталога ? jz st5 ; Нашли ! inc di ; Переход к следующему имени кат. mov point,di call read_cat ; Чт.найденного кат. в buf3 jmp st40 st5: call read_cat ; Чт.найденного кат. в buf3 ; Поиск защищаемого файла mov byte ptr f_flag,1 ; Ищется файл lea ax,fil_name ; Защищаемый файл mov point,ax mov cx,64 ; Кол. анализируемых записей lea si,buf3 ; Начало 1 записи каталога st51: cmp byte ptr [si],0 ; Пустая запись ? jz st52 ; Пропуск cmp byte ptr [si],0e5h ; Стертая запись ? jz st52 ; Пропуск call comp ; Сравнение с искомым cmp flag,1 ; Hайден ? jz st53 ; Найден st52: add si,32 ; Переход к следующей записи loop st51 ; Ошибка чтения lea dx,err_read mov al,6 call msg int 20h st53: mov ax,[si].b_clu ; В АХ начальный кластер этого файла ; Проверка флага инициализации test f_key,0ffh ; Проверка флага инициализации jz st54 ; Переход, если инициализации не было jmp nstart ; Переход на основную программу ; Инициализация st54: mov key,ax ; Запись начального кластера mov f_key,1 ; Установка флага инициализации ; Открытие файла mov ax,3d01h ; Открытие файла для записи lea dx,fil_name ; Имя файла int 21h jnc nst1 ; Ошибка чтения lea dx,err_read mov al,7 call msg int 20h nst1: mov handler,ax ; Установка указателя файла на 3 mov ax,4200h ; Абс. установка от начала mov bx,handler ; Дескриптор файла xor cx,cx ; Старшая часть смещения mov dx,3 ; Младшая часть смещения int 21h ; Запись в файл mov ah,40h ; Запись mov bx,handler ; Дескриптор файла mov cx,3 ; Количество записываемых байтов lea dx,key ; Смещение записываемых байтов int 21h jnc nst2 ; Ошибка чтения lea dx,err_read mov al,8 call msg int 20h nst2: ; Сообщение основной программы lea dx,ok mov al,0 call msg call kbin ; Ожидание int 20h nstart: cmp ax,key ; Сравн. истинного и зап. номеров jz nst2 ; Все в порядке ; Сообщение основной программы lea dx,nok mov al,0 call msg call kbin ; Ожидание int 20h ; Чтение подкаталога в buf3 ; Вход: SI = начало записи этого подкаталога в вышестоящем каталоге read_cat proc near mov bp,clu0 ; BP = лог.номер сект.первого доступного кластера lea bx,buf2 ; BR mov cl,[bx+11].clus_siz ; Секторов в кластере xor ch,ch mov ax,[si].b_clu ; Нач. кластер найд. кат. sub ax,2 ; Кластеры начинаются с 2 mul cx ; DX:AX нач.сект.найд.кат.отн.конца корн. add ax,bp adc dx,0 ; DX:AX лог.нач.сект.найд.кат. lea bx,b_param ; Блок параметров mov word ptr [bx].sec_num,ax ; Отн. номер сект. mov word ptr [bx+2].sec_num,dx ; Отн. номер сект. mov al,2 ; Диск С mov cx,-1 ; Признак > 32 M mov di,num_sec mov [bx].number_s,di ; Кол-во читаемых секторов mov [bx].b_off,offset buf3 mov dx,cs mov [bx].b_seg,dx int 25h ; Каталог в buf3 pop cx jnc rc1 ; Ошибки нет ; Ошибка чтения сектора lea dx,err_read mov al,5 call msg int 20h rc1: ret read_cat endp ; Сравнение тек. записи каталога с искомой (point) ; При успешном поиске: flag = 1 ; SI - нач. найденной записи comp proc near mov flag,0 ; Сброс флага поиска test byte ptr f_flag,0ffh ; Ищется файл ? jnz comp1 ; Да test byte ptr [si].f_attr,10h ; Подкаталог ? jnz comp1 ; Подкаталог ret ; Выход, если не подкаталог comp1: mov bp,si ; Нач. тек. имени в каталоге mov di,point ; Указ. тек. кат. push cx mov cx,11 comp2: mov al,byte ptr [di] ; Симв. тек. кат. cmp al,'.' ; Разделитель ? jnz comp3 ; Не разделитель inc di jmp comp2 ; Пропуск разделительной точки comp3: cmp al,'\' ; Конец имени ? jz comp31 ; Конец cmp al,0 ; Конец всего ? jnz comp4 ; Не конец ; Имя каталога совпало (имя короче 11 симв.) comp31: mov flag,1 ; Взведение флага поиска pop cx ret ; Выход при успешном поиске comp4: cmp byte ptr cs:[bp],20h ; Пробел ? jnz comp5 ; Не пробел inc bp dec cx jmp comp4 ; Пропуск пробела comp5: cmp al,cs:[bp] jz comp6 ; Символы совпали ; Символы не совпали pop cx ret ; Выход при несовпадении имен comp6: inc di ; Адрес в тек. каталоге inc bp ; Адрес в тек. записи каталога loop comp2 ; Имя каталога совпало (имя 11 симв.) mov flag,1 ; Взведение флага поиска pop cx ret ; Выход при успешном поиске comp endp ; Печать каталога pri_cat proc near mov cx,64 ; Кол. выводимых записей lea si,buf3 ; Начало 1 записи каталога pri_cat1: cmp byte ptr [si],0 ; Пустая запись ? jz pri_cat2 ; Пропуск cmp byte ptr [si],0e5h ; Стертая запись ? jz pri_cat2 ; Пропустить печать call c_file ; Печать строки pri_cat2: add si,32 ; Переход к следующей записи loop pri_cat1 ret pri_cat endp c_file proc near call wk pusha ; Печать имени файла push si mov cx,11 c_fil1: mov al,[si] call print inc si loop c_fil1 call sp4 ; Печать начального кластера pop si mov ax,[si].b_clu call prax call sp4 ; Печать размера файла mov ax,word ptr [si+2].f_size call prax mov ax,word ptr [si].f_size call prax popa ret c_file endp ; Вывод строки msg proc near push ax mov ah,9 int 21h pop ax or al,al jnz msg1 ret msg1: call prali ret msg endp ; Ввод с клавиатуры kbin proc near mov ah,0 ; Функция 0 int 16h ; клавиатурного прерывания ret kbin endp ; Печать 16 HEX байтов из [SI] hex proc near pusha mov cx,16 hex1: mov dl,[si] call pral call space ; Печать пробела inc si loop hex1 call wk ; Перевод строки, возврат каретки popa ret hex endp ; Печать АХ и ВК praxi proc near pusha call prax call wk popa ret praxi endp ; Печать AL и ВК prali proc near pusha call pral call wk popa ret prali endp ; Печать четырехзначного шестнадцатеричного числа из AX prax proc near push bx push cx push ax and ax,0f000h mov cl,12 shr ax,cl call prss pop ax push ax and ax,0f00h mov cl,8 shr ax,cl call prss pop ax push ax and ax,0f0h mov cl,4 shr ax,cl call prss pop ax push ax and ax,0fh call prss pop ax pop cx pop bx ret prax endp ; Печать двухзначного шестнадцатеричного числа из AL pral proc near pusha push ax mov cl,4 shr al,cl call prss pop ax call prss popa ret pral endp ; Перевод строки, возврат каретки wk proc near mov al,0dh ; Код возврата каретки call print ; Печать 1 ASCII символа mov al,0ah ; Код перевода строки jmp print ; Печать 1 ASCII символа wk endp ; Печать пробела space proc near mov al,32 ; Код пробела jmp print ; Печать 1 ASCII символа space endp ; Печать 4 пробелов sp4 proc near call space call space call space jmp space sp4 endp ; Печать одного hex символа из мл. тетр. al prss proc near and al,0fh add al,30h cmp al,39h jle print add al,7 ; Печать 1 ASCII символа print proc near pusha mov bx,0fh mov ah,0eh int 10h popa ret print endp prss endp Code ENDS END Start
ГЛАВА 3.
Популярное: Как распознать напряжение: Говоря о мышечном напряжении, мы в первую очередь имеем в виду мускулы, прикрепленные к костям ... Как выбрать специалиста по управлению гостиницей: Понятно, что управление гостиницей невозможно без специальных знаний. Соответственно, важна квалификация... Организация как механизм и форма жизни коллектива: Организация не сможет достичь поставленных целей без соответствующей внутренней... Как построить свою речь (словесное оформление):
При подготовке публичного выступления перед оратором возникает вопрос, как лучше словесно оформить свою... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (700)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |