30.05.2020, 08:46 [+3 UTC]
в нашей команде: 4 572 чел. | участники онлайн: 1 (рекорд: 21)

:: РЕГИСТРАЦИЯ

задать вопрос

все разделы

правила

новости

участники

доска почёта

форум

блоги

поиск

статистика

наш журнал

наши встречи

наша галерея

отзывы о нас

поддержка

руководство

Версия системы:
7.89 (25.04.2020)
JS-v.1.45 | CSS-v.3.39

Общие новости:
13.04.2020, 00:02

Форум:
29.05.2020, 13:47

Последний вопрос:
29.05.2020, 23:49
Всего: 152517

Последний ответ:
30.05.2020, 06:22
Всего: 260216

Последняя рассылка:
30.05.2020, 02:15

Писем в очереди:
0

Мы в соцсетях:

Наша кнопка:

RFpro.ru - здесь вам помогут!

Отзывы о нас:
11.11.2009, 11:38 »
Arkadiy
Спасибо! Прибор хороший, и я сам готов оплатить за его ремонт, но и в этом мне отказали. [вопрос № 174132, ответ № 256381]
27.05.2010, 22:19 »
Крупицын Игорь Викторович
Огромное спасибо! [вопрос № 178678, ответ № 261707]

РАЗДЕЛ • Assembler

Создание программ на языке Assembler.

[администратор рассылки: Лысков Игорь Витальевич (Мастер-Эксперт)]

Лучшие эксперты в этом разделе

Коцюрбенко Алексей Владимирович
Статус: Старший модератор
Рейтинг: 1551
Зенченко Константин Николаевич
Статус: Старший модератор
Рейтинг: 481
cain52
Статус: 3-й класс
Рейтинг: 7

Перейти к консультации №:
 

Консультация онлайн # 188427
Раздел: • Assembler
Автор вопроса: linda (Посетитель)
Отправлена: 14.12.2015, 16:49
Поступило ответов: 1

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

Хоть что-то можете подсказать?(

Состояние: Консультация закрыта

Здравствуйте, 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

5
нет комментария
-----
Дата оценки: 26.12.2015, 23:04

Рейтинг ответа:

+2

[подробно]

Сообщение
модераторам

Отправлять сообщения
модераторам могут
только участники портала.
ВОЙТИ НА ПОРТАЛ »
регистрация »

Мини-форум консультации № 188427

Лысков Игорь Витальевич
Мастер-Эксперт

ID: 7438

# 1

= общий = | 14.12.2015, 17:07 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:

Мы можем подсказать все smile
Но сначала скажите Вы:
1) Раз БИОС, то программа под ДОС
2) Выводить надо в графике... (Изучаете сейчас графику под ДОС-ом?) Какой предполагается номер режима?
3) Имена файлов обязательно на дискете?
4) Освободить лишнюю память не проблема, но зачем, собственно? Просто такое задание?

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

linda
Посетитель

ID: 399303

# 2

= общий = | 15.12.2015, 10:42 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Была бы очень признательна )
1) Да, MS DOS
2) Функция AH = 00 команды INT 10h
3) Думаю, не обязательно, можно на локальном диске
4) Задание такое

Есть код другого задания (может поможет) smile , но с теми же критериями, то есть
-Формат программы: EXE-программа;
-Ввод с клавиатуры: средствами BIOS;
-Вывод на экран: в графическом режиме;
-Динамическое распределение памяти: освободить лишнюю память
Задание: Переименовать файл NEWFILE.txt в файл OLDFILE.txt и установить у него атрибут <<ReadOnly>>

-----
 Прикрепленный файл:  скачать (DOCX) » [16.1 кб]

Зенченко Константин Николаевич
Старший модератор

ID: 31795

# 3

= общий = | 15.12.2015, 10:49 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:


© Цитата: linda
Функция AH = 00 команды INT 10h

Это понятно, вот какой AL = ?

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Лысков Игорь Витальевич
Мастер-Эксперт

ID: 7438

# 4

= общий = | 15.12.2015, 10:53 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Зенченко Константин Николаевич:

Судя из прикрепленного исходника:
mov AL, 0dh ; устанавливаем разрешение 320х200
smile

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

Лысков Игорь Витальевич
Мастер-Эксперт

ID: 7438

# 5

= общий = | 15.12.2015, 10:55 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:

Так Вам надо что-то подсказать или написать готовую программу?
Хотелось бы первое. smile Увидеть Ваши пробы, там подправили бы, исправили...

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

linda
Посетитель

ID: 399303

# 6

= общий = | 15.12.2015, 11:00 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Давайте, я попытаюсь)

Лысков Игорь Витальевич
Мастер-Эксперт

ID: 7438

# 7

= общий = | 15.12.2015, 11:04 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:

© Цитата:
Давайте, я попытаюсь)
Вот это замечательно! smile
Не переживайте, мы Вас одну не оставим! Поможем!

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

Лысков Игорь Витальевич
Мастер-Эксперт

ID: 7438

# 8

= общий = | 17.12.2015, 00:28 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:

Ну что там, получается?

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

linda
Посетитель

ID: 399303

# 9

= общий = | 17.12.2015, 22:56 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Я бы не сказала, что получается... разбирала разные коды, пыталась что-то понять, выделяла необходимое( по моему мнению) для себя
И вот какой гибрид получился
Я понимаю, что это чушь, я не знаю ассемблер

.model small
.stack 100h
.code

main:
mov ah, 00h
mov al, 0dh
int 10h

start:
mov ah,0eh
mov dl,02h
int 21h

mov ah,1ah
mov dx,offset dta
int 21h
jnc memory
memory:
mov ah,3dh
mov al,2h
mov dx,offset dta
int 21h
mov handle,ax

mov ah,42h
mov bx,handle
mov al,2h
mov cx,0h
mov dx,0h
int 21h

mov fsize_high,dx
mov fsize_low,ax
jnc print

print:
lea dx, mess1
call writedx
lea dx, fsize_high
call writedx
lea dx, fsize_low
call writedx

xor ax,ax
int 16h



writedx:
push ax
MOV AH,09H
int 21h
pop ax
ret

exit:

mov ah, 49h
int 21h
mov ah, 4Ch
int 21h


end main

Лысков Игорь Витальевич
Мастер-Эксперт

ID: 7438

# 10

= общий = | 18.12.2015, 11:01 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:

Ладушки, нарисую Вам программу (если меня не опередят smile ), только чуть позже... Занят несколько...

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

Зенченко Константин Николаевич
Старший модератор

ID: 31795

# 11

= общий = | 18.12.2015, 21:56 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:

Привет! Меняем стратегию.
1)смотрим на функции прерывания 21h - 48h | 49h | 4ah
это функции работы с памятью: выделение памяти, освобождение и изменение размера.

2)смотрим на функции прерывания 21h - 1ah | 4eh | 4fh
это функции поиска файлов и определения FCB
(File Control Block)-их есть два:
а)37 байт - совместимая с СР/М
+01h -имя файла(8 байт)
+09h - разширение(3 байта)
+10h - размер(4 байта)
в)44 байта - разширенная, чисто MS-DOS:
+00h - всегда 0FFh
+06h - атрибут файла
+08h - имя файла(8 байт)
+10h - разширение(3 байта)
+17h - размер(4 байта)
это поля и размер данных которые нужны Вам:

А)Пока займемся поиском файлов
1)Функцией 1Аh ставите свой DTA(FCB).
2)4Eh - поиск первого файла. Смотрим в FCB по нужным полям. Если нужно - куда либо копируем данные.
3)4Fh - поиск следущего файла. Смотрим в FCB по нужным полям. Если нужно - куда либо копируем данные.
Во всех случаях проверяем ошибку. Иногда она может сказать, что не нужно этого делать, а иногда может подсказать, что поиск закончен.
В)Будет работа спамятью
Если Игорь Витальевич до 20-го не сделает, я накатаю код
smile

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

linda
Посетитель

ID: 399303

# 12

= общий = | 18.12.2015, 22:09 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Была бы очень признательна)

Зенченко Константин Николаевич
Старший модератор

ID: 31795

# 13

= общий = | 18.12.2015, 22:28 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:

Вы пока сами попробуйте.
Главное нужно понимать, что :
Любая программа это:
1)получение данных(ввод с клавиатуры, задано в коде или любым другим способом, в Вашем слечае поиск файлов smile );
2)обработка(тут может быть, что угодно, в Вашем случае сортировка smile );
3)вывод результата.
Разбивая любую программу на этапы, Вы всегда можете получить рузультат. Только не пытайтесь сделать все и сразу. Без опыта это ведет к появлению ошибок, при исправлении - к новым, короче замкнутый круг.
smile
Потом начинается
smile smile smile
smile
Не переживайте прорвемся.

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

Лысков Игорь Витальевич
Мастер-Эксперт

ID: 7438

# 14

= общий = | 19.12.2015, 22:03 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Зенченко Константин Николаевич:

© Цитата:
Если Игорь Витальевич до 20-го не сделает, я накатаю код
Сделал вот smile smile smile

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

Зенченко Константин Николаевич
Старший модератор

ID: 31795

# 15

= общий = | 20.12.2015, 10:37 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

smile

=====
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.
smile

linda
Посетитель

ID: 399303

# 16

= общий = | 20.12.2015, 11:26 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Большое спасибо smile думаю без вопросов не обойдется

linda
Посетитель

ID: 399303

# 17

= общий = | 20.12.2015, 12:46 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

А вот через эти команды нельзя выполнить сортировку в моем случае?
http://www.cyberforum.ru/post4770617.html

Сортировка списка отображаемых файлов.
S По размеру (сперва меньшие)

Лысков Игорь Витальевич
Мастер-Эксперт

ID: 7438

# 18

= общий = | 20.12.2015, 13:58 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:

Можно по-разному... Но!
Вас устроит тот вывод, который дает DIR? Меня бы не устроил. Лично я хочу выводить так, как я хочу,
а не довольствоваться выводом стандартной команды.
А если начнете разбирать вывод команды DIR, то код получится еще больше, чем у меня smile
PS Зачем тогда учиться писать программы? smile
PPS Впрочем, если хотите использовать DIR, никто Вам не вправе запретит это сделать! Пробуйте!
Как минимум, попытка вызова команды тоже пойдет Вам на пользу!
Если что, можете выложить сюда свои эксперименты, подправим... smile

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

linda
Посетитель

ID: 399303

# 19

= общий = | 23.12.2015, 00:35 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Объясните пожалуйста эти строки
1) dta_name db 13 dup (?) ;имя файла ASCIIZ, заканчивающееся 0
Это 13 неопределенных байт?
Почему на 0 заканчивается?

2) mov ah, 4ah ;функция изменения размера блока
Как изменяется?

3) add al, 'A' ;делаем из номера букву
Какой номер? Почему А?

4) add si,3 ;на позицию собственно имени директории
?

Лысков Игорь Витальевич
Мастер-Эксперт

ID: 7438

# 20

= общий = | 23.12.2015, 00:54 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:

1) Область ДТА сначала пустая, но после вызова функций 4eh/4fh заполняется информацией
И в поле dta_name будет имя файла с 0 в конце
2) Меняется размер сегмента, адрес которого в ES, новый размер в параграфах (1 параграф = 16 байт) в регистре BX
3) потому что, функция возвращает для диска А - al=0, для диска В - al=1, C - al=2, и т.д. Чтобы получить букву диска из номера, я и прибавляю код символа 'A'
4) Функция получения имени текущей директории возвращает только путь без диска. Я перед путем сначала формирую <диск>:\
Как раз три байта, затем смещаем адрес в SI на 3, куда запишется путь. И получим полный путь с диском.

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

linda
Посетитель

ID: 399303

# 21

= общий = | 23.12.2015, 23:30 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

А что в этих строках происходит? smile
1) lea di,[si+size _files] ;второй начинается со следующего
size _files - это ...?
[si+size _files] - ..?

2) mov ax,ds:[_files ptr bp].files_size_hi ;сначала старшее слово
Почему точка?
ds: ?

Лысков Игорь Витальевич
Мастер-Эксперт

ID: 7438

# 22

= общий = | 24.12.2015, 01:22 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:

1) Исключительно ради удобства я свел все, что касается одного элемента, описывающего имя файла, его длину, а также поле для сортировки в структуру

_files      struc         
files_name   db   13 dup (?)   ;имя файла ASCIIZ 
files_size_lo   dw   ?         ;младшее слово длины файла 
files_size_hi   dw   ?         ;старшее слово длины файла 
files_pointer   dw   ?         ;указатель на структуру _files 
_files      ends
_files - имя этой структуры
Остальные имена - фактически,смещение от начала структуры, например,
files_name = 0
files_size_lo = 13 и т.д.
size _files - это длина структуры _files (и равна 19)
Далее, область памяти files - это массив структур _files.
Сортировка "пузырьком" предполагает последовательное сравнение всех со всеми и "всплывание"
самого меньших к началу. Для этого организовывается два цикла:
первый - по адресу в si, который адресует элемент, который будет сравниваться с последующими
второй - по адресу в di, который адресует последующих
И этот второй начинается с адреса элемента, следующего за первым. А т.к. элементы имеют длину size _files = 19
то и di = si+size _files

2) точка положена по синтаксису, когда используется имя поля структуры. Фактически данное смещение добавляется
к адресу из регистра, т.е. будет [bp+files_size_hi] Там еще спереди добавлено _files ptr, которое говорит, из какой структуры поле.
А DS: необходимо по причине того, что регистр BP по умолчанию работает в сегменте стека SS, а не данных DS
Чтобы указать на сегмент данных, и пишем префикс DS:

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

linda
Посетитель

ID: 399303

# 23

= общий = | 24.12.2015, 23:54 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Большое спасибо))

linda
Посетитель

ID: 399303

# 24

= общий = | 26.12.2015, 23:17 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

1) а почему подпрограмма корректно выведет число именно до 6553500000?

В сортировке:
2) указатель - это как номер элемента массива?
Здесь не совсем понимаю...
3) Sort_loop1: ;цикл по первому указателю
lea di,[si+size _files] ;второй начинается со следующего
4) Sort_next2:
add di,size _files ;второй указатель - на следующий элемент


Лысков Игорь Витальевич
Мастер-Эксперт

ID: 7438

# 25

= общий = | 27.12.2015, 00:43 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:

© Цитата:
1) а почему подпрограмма корректно выведет число именно до 6553500000?

Во-первых, не до 6553500000, а до 655350000
Потому что, подпрограмма сначала делит на 10000. Максимальное число, которое останется после деления и поместится в слово равно 0ffffh = 65535.
© Цитата:
В сортировке:
2) указатель - это как номер элемента массива?
Здесь не совсем понимаю...
Указатель не номер элемента массива, а адрес этого элемента
© Цитата:
3) Sort_loop1: ;цикл по первому указателю
lea di,[si+size _files] ;второй начинается со следующего
В подпрограмме сортировке для доступа к элементам массива используются адреса этих элементов. Каждый цикл по всем последующим элементам начинается тем, что адрес, с которого будут рассматриваться все последующие элементы, равен первому плюс длина одного элемента, т.е. следующий за первым.
© Цитата:
4) Sort_next2:
add di,size _files ;второй указатель - на следующий элемент
после рассмотрения очередного последующего переходим на один дальше, для чего опять же добавляем к указателю длину одного элемента.

PS Надо, в общем-то знать, как работает "пузырьковая" сортировка...

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

linda
Посетитель

ID: 399303

# 26

= общий = | 27.12.2015, 14:41 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

еще такой вопрос: освобождение памяти в программе правильно выполняется?

Просто некоторые написали так:
mov ah,4ah ;функция изменения размера блока памяти
mov bx,((csize/16)+1)+256/16+((dsize/16)+1)+256/16;новый размер программы с учетом всех сегментов
int 21h ;ограничиваем блок данных нашей программы

Лысков Игорь Витальевич
Мастер-Эксперт

ID: 7438

# 27

= общий = | 27.12.2015, 15:33 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
linda:

© Цитата:
освобождение памяти в программе правильно выполняется?
Правильно
© Цитата:
Просто некоторые написали так:
mov bx,((csize/16)+1)+256/16+((dsize/16)+1)+256/16;новый размер программы с учетом всех сегментов

Кстати, Вы обратили внимание, что в моей программе под стек выделено не 256 байт, а 256 слов
Стеку надо выделять не байты, а слова! Вершина стека адресует слово!
Команду
mov bx,((csize/16)+1)+256/16+((dsize/16)+1)+256/16;
надо исправить на
mov bx,((csize/16)+1)+256/16+((dsize/16)+1)+512/16;
Можно писать по-разному.
В моей программе (кстати. я скопировал из приведенного примера) конец программы считается автоматически,
как адрес последнего сегмента.
В приведенной формуле задаются длины используемых сегментов, переведенных в параграфы.
+1 для сегментов кода и данных необходимо, чтобы учесть, возможно, не полностью заполненный
последний параграф.
Первые 256/16 - для сегмента PSP (первые 100h байт перед программой)
Вполне нормальный способ. smile (с учетом моей поправки о длине стека)
Результат - один и тот же smile
Правда, цифры могут отличаться, в случае, когда размер сегментов кода или данных будут кратны 16.
Но это абсолютно не важно для работы программы!

-----
Последнее редактирование 27.12.2015, 15:36 Лысков Игорь Витальевич (Мастер-Эксперт)

=====
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен

linda
Посетитель

ID: 399303

# 28

= общий = | 27.12.2015, 15:49 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Спасибо огромное)))

 

Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.

Rambler's Top100

главная страница | поддержка | задать вопрос

Время генерирования страницы: 0.20436 сек.

© 2001-2020, Портал RFPRO.RU, Россия
Калашников О.А.  |  Гладенюк А.Г.
Версия системы: 7.89 от 25.04.2020
Версия JS: 1.45 | Версия CSS: 3.39