WMmail.ru - сервис почтовых рассылок

четверг, 24 декабря 2015 г.

RFpro.ru: Ассемблер? Это просто! Учимся программировать

 
Если выпуск не отображается, вы можете прочесть его на сайте
  

  
T22C350 T22C350
Купить за 11750 руб. Подробнее...

  Диплом, не выходя из дома! Диплом, не выходя из дома!
Диплом-дистанционно! Подарки при поступлении! Ежемесячное зачисление!

  Высшее образование с МТИ! Высшее образование с МТИ!
Учись дистанционно в МТИ! 2 диплома! Подарки при поступлении!

 
  
     
   RFpro.ru: Ассемблер? Это просто! Учимся программировать
  

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Коцюрбенко Алексей aka Жерар
Статус: Советник
Рейтинг: 2975
• повысить рейтинг »
Асмик Гаряка
Статус: Советник
Рейтинг: 27
• повысить рейтинг »
Куликов Роман Евгеньевич
Статус: 1-й класс
Рейтинг: 0
• повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска:1577
Дата выхода:24.12.2015, 17:21
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:17 / 7
Вопросов / ответов:1 / 1

Консультация # 188427: Здравствуйте! У меня возникли сложности с таким вопросом: smile нужно вывести на экран имена файлов на дискете в порядке увеличения их размера это EXE - программа, ввод с клавиатуры средствами BIOS, вывод на экран в графическом режиме Динамическое распред...

Консультация # 188427:

Здравствуйте! У меня возникли сложности с таким вопросом: smile
нужно вывести на экран имена файлов на дискете в порядке увеличения их размера
это 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 штук  smile    data ends    ; описываем сегмент стека  stk segment stack  	dw 256 dup (?)	; выделяем под стек 256 слов  stk ends    abcd segment 'endseg'	; фиктивный сегмент для определения размера программы  abcd ends  	end PROGRAM_START	; конец программы    

Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 19.12.2015, 21:58
Рейтинг ответа:

НЕ одобряю +2 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!

 
     Прошлые выпуски
RFpro.ru: Ассемблер? Это просто! Учимся программироватьRFpro.ru: Ассемблер? Это просто! Учимся программироватьRFpro.ru: Ассемблер? Это просто! Учимся программироватьВсе выпуски рассылки
 
 
Subscribe.Ru / АО «Интернет-Проекты» / О компании / Политика конфиденциальности

Комментариев нет:

Отправить комментарий