Консультация № 181737
04.01.2011, 18:43
52.95 руб.
05.01.2011, 02:39
0 12 1
Здравствуйте, уважаемые эксперты! Прошу Вас переделать программу под байты...
[code h=200];В массиве а(10) отсортировать все элементы по возростанию до первого кратного 7
.model small
.data
sEnter db 'Enter 10 numbers: ','$'
sTitle db 'Sorted array: $'
a dw 10 dup (?)
len_a equ 10 ;число элементов
sNum db 80 ;максимальный размер буфера
sBuf db 80 dup (?) ;сама строка


.code

mov ax, @DATA
mov ds, ax
mov es, ax

push offset a ;параметром - адрес массива
call GetArray ;вводим массив

;найдем число элементов до первого кратного 7
lea si, a ;адрес массива
mov cx, len_a ;всего элементов
xor bx, bx ;искомый счетчик
mov di, 7 ;делим на 7
search_div7:
lodsw ;очередной элемент
cwd ;подготовим dx:ax к делению
idiv di ;ds:ax / 7
cmp dx, 0 ;остаток есть?
jz sort ;нет - разделилось нацело, идем на сортировку
inc bx ;считаем
loop search_div7

;отсортируем bx элементов методом пузырька
sort:
mov cx, bx ;число сортируемых элементов
dec cx ;число сравнений
lea si, a ;адрес элемента в массиве
SortLoop: ;цикл по поиску очередного минимального
lea di, [si+2] ;начинаем со следующего
push cx ;сохраним счетчик
mov ax, [si] ;текущий минимальный по адресу [si]
SearchMinLoop: ;цикл по всем последующим
;сравниваем текущий со всеми последующими
cmp ax, [di] ;если текущий минимальный <= последующего,
jle SortNext ; то обходим обмен
;меняем местами элементы
xchg ax, [di]
mov [si], ax ;по адресу [si] и в ax новый минимальный
SortNext:
inc di
inc di ;на следующий последующий
loop SearchMinLoop
inc si
inc si ;на следующий текущий
pop cx ;восстановим счетчик сравнений
loop SortLoop

print: ;выведем все элементы
lea dx, sTitle
mov ah, 9
int 21h ;заголовок

mov cx, len_a ;число всех
lea si, a ;адрес
PutLoop:
lodsw ;элемент
call PutNumber ;выводим
loop PutLoop

mov ah, 0
int 16h ;ждем нажатие на клавишу

mov ax, 4c00h ;выход в ДОС
int 21h

PutNumber proc ;преобразование числа из ax в строку и вывод на экран
push cx bx ;сохраним использованые регистры
xor cx, cx ;счетчик разрядов
mov bx, 10 ;делим на 10
DivLoop: ;цикл преобразования в разряды
cwd ;подготавливаем dx:ax к делению
idiv bx ;dx = очередному младшему разряду
push dx ;сохраним в стеке
inc cx ;считаем
cmp ax, 0 ;продолжаем, пока не дойдем до 0
jnz DivLoop
PrLoop: ;цикл вывода в обратном порядке
pop ax ;берем число 0-9 из стека
or al, '0' ;преобразовываем в символ '0'-'9'
int 29h ;выводим
loop PrLoop
mov al, ' '
int 29h ;отделим пробелом
pop bx cx
ret
PutNumber endp

GetArray proc pArray:word ;ввод массива
local pLast:word ;переменная для сравнения на конец

push bp
mov bp, sp ;адресуем параметр через [bp+4]
sub sp, 2 ;2 байта под локальную переменную pLast

lea dx, sEnter
mov ah, 9
int 21h ;приглашение на ввод элементов массива

mov di, pArray ;адрес массива

mov ax, len_a ;адрес за массивом (для контроля конца)
shl ax, 1
add ax, pArray
mov pLast, ax ;сохраним
GA_ask:
mov ah, 2
mov dl, 0ah
int 21h ;переход на новую строку

lea dx, sNum
mov ah, 0ah
int 21h
lea si, sBuf ;строка с числами, разделенная разделителями

GA_next:
cmp di, pLast ;массив заполнен?
je GA_ret

call stoi ;[si] -> ax
jcxz GA_ask ;дошли до конца строки?
stosw ;сохраняем
jmp GA_next ;на следующее число в строке
GA_ret:
mov sp, bp ;восстановим вершину стека
pop bp ;восстановим старое значение bp
ret
GetArray endp

;функция преобразовывает числовую строку в число
;преобразование заканчивается по любому разделителю или концу строки (0dh)
;признаком конца строки является cx = 0
stoi proc ;преобразование строки [si] в беззнаковое число AX
push dx
xor bx, bx ;здесь будем стоить число
xor cx, cx ;счетчик разрядов
stoi_next:
lodsb ;очередной символ
cmp al, 0dh ;конец стоки?
je stoi_eol
cmp al, '0'
jb stoi_sep ;любая нецифра - разделитель
cmp al, '9'
ja stoi_sep
push ax ;сохраним новый разряд
mov ax, 10
mul bx ;умножим старшие на 10
pop dx ;новый
and dx, 0fh ;'0'-'9' -> 0-9
add ax, dx ;добавляем новый разряд
mov bx, ax ;сохраняем
inc cx ;считаем
jmp stoi_next ;продолжаем
stoi_sep: ;встретили разделитель
jcxz stoi_next ;были только разделители - на продолжение
; иначе - конец числа и выходим
stoi_eol: ; если числа нет и встретили 0dh - конец строки
mov ax, bx ;число возвращаем в ax
dec si ;шаг назад, чтобы легче было проанализировать 0dh
pop dx
ret
stoi endp

end[/code]

Обсуждение

Неизвестный
04.01.2011, 18:44
общий
или написать новую... и просьба комментарии к каждой строчке
давно
Посетитель
7438
7205
04.01.2011, 18:53
общий
Ок, сделаем. Надо сразу указывать, что требуется.
Имеющихся комментариев недостаточно?
И еще: что вводим? Символы или числа, размером с байт (<256)?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
04.01.2011, 18:56
общий
числа, комментарии к новым строчкам имеется в виду. как я понял массив должен выглядить в виде строки из 10 цифр
давно
Посетитель
7438
7205
04.01.2011, 19:03
общий
Все-таки имеем строку символов-цифр, а не чисел... Ок. Программа, в таком случае, значительно упрощается. Вечерком сегодня подправлю...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
04.01.2011, 19:10
общий
пасиба =) жду
давно
Посетитель
7438
7205
05.01.2011, 02:37
общий
это ответ
Здравствуйте, Евтеев Алексей Николаевич!
Вот Вам пограмма. Если что непонятно, обращайтесь в мини-форум.

[code h=200];В массиве а(10) отсортировать все элементы по возрастанию до первого, кратного 7

.model small
.stack 512
.data
strA db 'Enter 10 numbers: $'
sTitle db 0dh,0ah,'Sorted array: $'
strAny db 0dh,0ah,'Press any key$'
lenA equ 10 ;длина строки
A db lenA dup (?) ;строка

.code
start: mov ax, @data
mov ds, ax
mov es, ax

lea dx, strA
mov ah, 9
int 21h ;строка приглашения для ввода А

lea di, A ;адрес массива А
mov cx, lenA ;длина массива А
c1: mov ah, 8 ;функция ввода кода без отображения
c2: int 21h
cmp al, '0' ;проверка на цифру
jb c2 ;нецифру игнорируем
cmp al, '9'
ja c2
mov dl, al ;сохраним для вывода
and al, 0fh ;превратим в число
stosb ;сохраним
mov ah, 2 ;функция вывода символа из dl
int 21h
loop c1 ;по всем

;найдем число элементов до первого кратного 7
lea si, A ;адрес массива
mov cx, lenA ;всего элементов
xor bx, bx ;искомый счетчик
mov dl, 7 ;делим на 7
search_div7:
lodsb ;очередной элемент
cbw ;подготовим ax к делению
idiv dl ;ax / 7
cmp ah, 0 ;остаток есть?
jz sort ;нет - разделилось нацело, идем на сортировку
inc bx ;считаем
loop search_div7

;отсортируем bx элементов методом пузырька
sort:
mov cx, bx ;число сортируемых элементов
dec cx ;число сравнений
lea si, a ;адрес элемента в массиве
SortLoop: ;цикл по поиску очередного минимального
lea di, [si+1] ;начинаем со следующего
push cx ;сохраним счетчик
mov al, [si] ;текущий минимальный по адресу [si]
SearchMinLoop: ;цикл по всем последующим
;сравниваем текущий со всеми последующими
cmp al, [di] ;если текущий минимальный <= последующего,
jle SortNext ; то обходим обмен
;меняем местами элементы
xchg al, [di]
mov [si], al ;по адресу [si] и в al новый минимальный
SortNext:
inc di ;на следующий последующий
loop SearchMinLoop
inc si ;на следующий текущий
pop cx ;восстановим счетчик сравнений
loop SortLoop

print: ;выведем все элементы
lea dx, sTitle
mov ah, 9
int 21h ;заголовок

mov cx, lenA ;число всех
lea si, a ;адрес
mov ah, 2
PutLoop:
lodsb ;элемент
or al, '0'
mov dl, al
int 21h ;выводим
loop PutLoop

lea dx, strAny
mov ah, 9
int 21h ;строка приглашения нажатия на любую клавишу

mov ah, 8
int 21h ;ждем нажатие на клавишу

mov ax, 4c00h ;выход в ДОС
int 21h

end start
[/code]
5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
05.01.2011, 17:36
общий
Код:
search_div7:
lodsb ;очередной элемент
cbw ;подготовим ax к делению
idiv dl ;ax / 7
cmp ah, 0 ;остаток есть?
jz sort ;нет - разделилось нацело, идем на сортировку
inc bx ;считаем
loop search_div7


почему
Код:
cbw			;подготовим ax к делению         
idiv dl ;ax / 7
а не div dl
давно
Посетитель
7438
7205
05.01.2011, 23:16
общий
Добрый вечер. Только добрался до компьютера.
Можно и div dl. В нашем случае они будут работать одинаково.
Отличия будут, когда будут величины 80h-ffh
Тогда поменяйте и cbw на mov ah,0
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
05.01.2011, 23:31
общий
а что mov ah,0 делает
Неизвестный
05.01.2011, 23:31
общий
просто смысл непойму
Неизвестный
05.01.2011, 23:45
общий
в ah же остаток вроде записуется
давно
Посетитель
7438
7205
06.01.2011, 00:58
общий
Смысл в том, что команда div (и idiv тоже) делит слово в ax на байт dl
После деления, все правильно, в ah будет остаток, а до деления там должен быть 0!
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа