РАССЫЛКИ ПОРТАЛА RFPRO.RU Лучшие эксперты по данной тематике Номер выпуска: | 1577 | Дата выхода: | 24.12.2015, 17:21 | Администратор рассылки: | Лысков Игорь Витальевич (Старший модератор) | Подписчиков / экспертов: | 17 / 7 | Вопросов / ответов: | 1 / 1 | Консультация # 188427: Здравствуйте! У меня возникли сложности с таким вопросом: нужно вывести на экран имена файлов на дискете в порядке увеличения их размера это EXE - программа, ввод с клавиатуры средствами BIOS, вывод на экран в графическом режиме Динамическое распред... Консультация # 188427: Здравствуйте! У меня возникли сложности с таким вопросом: нужно вывести на экран имена файлов на дискете в порядке увеличения их размера это EXE - программа, ввод с клавиатуры средствами BIOS, вывод на экран в графическом режиме Динамическое распределение памяти: освободить лишнюю память.
Хоть что-то можете подсказать?(
Дата отправки: 14.12.2015, 16:49 Вопрос задал: muhaeva.elza (Посетитель) Всего ответов: 1 Страница онлайн-консультации » Консультирует Лысков Игорь Витальевич (Старший модератор): Здравствуйте, muhaeva.elza! Держите программу. В ней много разных интересных моментов, например, использование структур, а особенно, реализация сортировки... Изучайте, вникайте... Будут вопросы - спрашивайте. Но программа достаточно неочевидная, без самостоятельного скурпулезного разбора у Вас ничего не получится!
Код (Assembler): TITLE FAIL(EXE) assume CS:code, DS:data ;некоторые структуры для удобства адресации данных _dta struc ;ДТА dta_res db 21 dup(?) ;резерв dta_attr db ? ;атрибут файла dta_time dw ? ;время файла dta_date dw ? ;дата файла dta_size_lo dw ? ;младшее слово длины файла dta_size_hi dw ? ;старшее слово длины файла dta_name db 13 dup (?) ;имя файла ASCIIZ, заканчивающееся 0 _dta ends ;структура, описывающая элемент для хранения найденного ;имени файла, его длины, а также поле, используемое для сортировки _files struc files_name db 13 dup (?) ;имя файла ASCIIZ files_size_lo dw ? ;младшее слово длины файла files_size_hi dw ? ;старшее слово длины файла files_pointer dw ? ;указатель на структуру _files _files ends ;структура, описывающая элемент для печати строки _print struc print_pos dw ? ;позиция курсора, low - колонка, high - строка print_pstr dw ? ;указатель на строку ASCIIZ _print ends ; описываем сегмент кода code segment PROGRAM_START: ; метка точки входа программы ; настройка регистра DS mov AX, data mov DS, AX ; освобождение памяти mov AX, abcd ; сегментный адрес конца программы mov DX, ES ; сегментный адрес начала программы sub AX, DX ; размер программы в параграфах mov BX, AX ; оставим его в BX mov AH, 4ah ; функция изменения размера блока int 21h mov ax, 000dh ;переходим в графический режим 320х200 int 10h lea si, directory ;адрес буфера для имени текущей директории call GetDir ;сформируем имя текущей директории lea di, text ;адрес массива, задающего набор строк для вывода call print_text ;выводим текст на экран call FindFiles ;ищем все файлы в текущей директории call SortFiles ;сортируем по возрастанию длины файла call PrintFiles ;выводим на экран mov ah, 0 int 16h mov ax, 0003h ;возвращаемся в текстовый режим int 10h mov ax, 4c00h INT 21h ;вызов прерывание окончания работы программы ;вывод массива текста на экран ;параметр: di - адрес массива _print print_text proc near mov dx, [_print ptr di].print_pos ;строка, колонка cmp dx, -1 ;дошли до конца? je print_text_ret mov si, [_print ptr di].print_pstr ;адрес строки call print_str ;выводим с указанной позиции add di, size _print ;на следующий элемент массива структур jmp print_text print_text_ret: ret print_text endp ;вывод строки [si] с указанной [dx] позиции print_str proc near mov ah, 2 xor bx, bx int 10h ;позиция курсора print_str_loop: lodsb cmp al, 0 ;строка заканчивается нулем je print_str_ret mov ah, 0eh ;функция выводит в текущей позиции курсора и ;автоматически смещает курсор на 1 вправо mov bl, 0eh ;атрибут int 10h jmp print_str_loop print_str_ret: ret print_str endp ;получаем имя полного пути текущей директории в [si] GetDir proc near mov ah, 19h ;текущий диск, 0 - А int 21h add al, 'A' ;делаем из номера букву mov [si], al mov ax,'\:' ;отделяем <диск>:/ mov word ptr [si+1], ax add si,3 ;на позицию собственно имени директории mov ah, 47h ;функция получения имени полного пути текущей директории mov dl,0 ;текущего диска int 21h ret GetDir endp ;поиск всех файлов и заполнение массива структур _files FindFiles proc near lea dx, dta ;зададим область DTA, необходимую для поиска mov ah, 1ah int 21h lea di, files ;адрес массива _files xor bp, bp ;счетчик файлов lea dx, spec ;маска файлов "*.*" mov cx, 0 ;атрибут файлов, которые ищем mov ah,4eh ;начало поиска search_loop: int 21h jc f_end ;ищем, пока ищется. В конце будет С=1 и АХ=12h ;возможны другие ошибки, но мы их для простоты ;проверять не будем, даже 12h. Выходим из поиска по С=1 lea si,dta.dta_name ;адрес имени файла в ДТА ;копируем в элемент массива _files xor bx,bx ;будем индексировать с помощью bx copy_name_loop: lodsb mov [_files ptr di+bx].files_name, al inc bx cmp al,0 ;копируем, включая завершающий 0 jne copy_name_loop ;копируем длину файла mov ax, word ptr dta.dta_size_lo mov [_files ptr di].files_size_lo,ax mov ax, word ptr dta.dta_size_hi mov [_files ptr di].files_size_hi,ax mov [_files ptr di].files_pointer,di add di,size _files ;на следующий элемент _files inc bp ;считаем mov ah,4fh ;продолжение поиска, dx не должен портиться! jmp search_loop f_end: mov cx,bp ;возвращаем в СХ количество найденных файлов ret FindFiles endp ;Сортировка массива files по увеличению длины файла ;Используется сортировка "пузырьком" ;Чтобы меньше менять местами, введено поле указателя, ;которое и будет меняться местами SortFiles proc near lea si,files ;адрес массива ;найдем адрес последнего элемента массива ;будем по нему определять конец массива mov ax,size _files ;размер элемента массива mul cx ;умножаем на их количество add ax,offset files - size _files ;минус размер одного mov dx,ax ;dx - адрес последнего элемента массива Sort_loop1: ;цикл по первому указателю lea di,[si+size _files] ;второй начинается со следующего Sort_loop2: ;цикл по второму указателю cmp di,dx ;второй дошел до конца массива? ja Sort_next1 ;если да, то на увеличение первого указателя mov bx,[_files ptr si].files_pointer ;получаем укзатели на элементы mov bp,[_files ptr di].files_pointer ;и сравниваем длины файлов mov ax,ds:[_files ptr bp].files_size_hi ;сначала старшее слово cmp ax,[_files ptr bx].files_size_hi ;сравнение беззнаковое! jb Sort_change ;если второй меньше первого, то меняем местами ja Sort_next2 ;если больше, то на увеличение второго указателя mov ax,ds:[_files ptr bp].files_size_lo ;если равно, то сравниваем младшее слово cmp ax,[_files ptr bx].files_size_lo jae Sort_next2 ;если больше или равно, то на увеличение второго указателя Sort_change: ;меняем местати mov ax,[_files ptr di].files_pointer ;указатели в массиве xchg ax,[_files ptr si].files_pointer mov [_files ptr di].files_pointer,ax xchg bx,bp ;и в регистрах Sort_next2: add di,size _files ;второй указатель - на следующий элемент jmp Sort_loop2 Sort_next1: add si,size _files ;увеличиваем первый указатель cmp si,dx ;дошли до последнего? jb Sort_loop1 ;нет - продолжаем ret SortFiles endp ;вывод имен файлов с их длинами ;cx - количество элементов массива ;выводим только столько, сколько помещается на экран, не более 17 PrintFiles proc near lea si,files ;адрес массива files mov bp,0804h ;начальная позиция курсора cmp cx,17 ;проверим количество jle print_names_loop mov cx,17 print_names_loop: mov dx,bp ;позиция для очередного элемента push si ;сохраним адрес элемента массива mov si,[_files ptr si].files_pointer ;адрес отсортированного элемента массива push si ;сохраним его call print_str ;выводим имя файла pop si ;вернем адрес элемента массива mov ax,[_files ptr si].files_size_lo ;длина файла mov dx,[_files ptr si].files_size_hi call PrintLen ;преобразуем число в строку и выведем pop si ;вернем адрес в неотсортированном массиве add si,size _files ;на следующий элемент add bp,0100h ;смещаемся на строку ниже loop print_names_loop ret PrintFiles endp ;вывод числа dx:ax в виде строки ;строка выравнивается по правому краю ;подпрограмма корректно выведет число до 655350000 PrintLen proc near push cx ;сохраним счетчик элементов lea di,number ;адрес буфера для строки-числа mov si,di ;запомним для вывода mov cx,' ' ;очистим 14 байт пробелами mov [di],cx mov [di+2],cx mov [di+4],cx mov [di+6],cx mov [di+8],cx mov [di+10],cx mov [di+12],cx mov byte ptr [di+15],0 ;закроем строку нулем add di,14 ;на адрес последнего символа ;заполнять будем от младшего к старшему mov cx,10000 ;разделим сначала на 10000 ;сразу делить на 10 нельзя! ;может дать ошибку для больших чисел div cx mov cx,10 ;дальше будем делить на 10 test ax,ax ;число больше 10000? jne big_number ;да, сначала выведем младшие 4 разряда mov ax, dx ;<10000 - выводим число заведомо меньшее 10000 jmp small_number big_number: ;выводим ровно 4 младшие цифры push ax ;сохраним частное для дальнейшего вывода mov ax,dx ;выводим остаток (4 младшие цифры) xor dx,dx div cx or dl,'0' mov [di],dl ;единицы dec di xor dx,dx div cx or dl,'0' mov [di],dl ;десятки dec di xor dx,dx div cx or dl,'0' mov [di],dl ;сотни dec di or al,'0' mov [di],al ;тысячи dec di pop ax small_number: ;выводим столько разрядов, сколько есть xor dx,dx div cx or dl,'0' mov [di],dl ;очередной разряд dec di test ax,ax jne small_number ;пока есть что-то mov dx,bp ;позиция вывода add dx,15 ;вправо на 15 колонок call print_str ;выводим строку-число на экран pop cx ret PrintLen endp code ends ;конец сегмента кода ; описание сегмента данных (переменные) data segment ;массив для вывода кста на экран text _print <0011h,cout1> _print <0104h,cout2> _print <020ch,cout3> _print <0308h,cout4> _print <040fh,cout5> _print <050ah,cout6> _print <0604h,directory> _print <-1> ;признак конца массива COUT1 DB "Rabota",0 COUT2 DB "Sistemnoe programnoe obespecenie",0 COUT3 DB "Studenta gruppi ",0 COUT4 DB "FIO",0 COUT5 DB "Variant #4",0 COUT6 db "Spisok failov v papke:",0 spec db "*.*",0 ;маска для поиска файлов number db 16 dup(?) ;буфер для преобразования числа в строку directory db 64 dup(?) ;буфер для имени текущей директории dta _DTA <> ;область ДТА для поиска files _files 1000 dup(<>) ;массив для хранения найденных имен файлов и их длин ;максимально - 1000 штук data ends ; описываем сегмент стека stk segment stack dw 256 dup (?) ; выделяем под стек 256 слов stk ends abcd segment 'endseg' ; фиктивный сегмент для определения размера программы abcd ends end PROGRAM_START ; конец программы
Оценить выпуск | Задать вопрос экспертам главная страница | стать участником | получить консультацию техническая поддержка | восстановить логин/пароль Дорогой читатель! Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно! МЫ РАБОТАЕМ ДЛЯ ВАС! |
Комментариев нет:
Отправить комментарий