Консультация № 187354
19.05.2013, 18:46
299.47 руб.
0 3 1
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:

С клавиатуры вводится матрица элементов (чисел) размерности 5x5
Необходимо вывести на экран максимальный номер столбца, в котором все числа - двузначные. Если такого столбца нет, вывести соответствующее сообщение.

Задача для TASM, model small
Прошу как можно подробнее расписать комментарии к программе. Заранее благодарен.

Обсуждение

давно
Посетитель
7438
7205
19.05.2013, 23:18
общий
это ответ
Здравствуйте, Козлов Олег Николаевич!
Вот Вам программа.
Числа можно вводить разделенными, например, пробелами, по несколько штук в строке.
Удобнее всего, по 5.
[code h=200];С клавиатуры вводится матрица элементов (чисел) размерности 5x5
;Необходимо вывести на экран максимальный номер столбца, в котором все числа -
;двузначные. Если такого столбца нет, вывести соответствующее сообщение.

.model small

.data
sMatrix db 'Enter matrix 5x5 (row by row):',0dh,'$';приглашение для ввода элементов
sSource db 0ah,0ah,'Source matrix:',0dh,0ah,'$'
sColumn db 0dh,0ah,'Founded column: $'
sNotFound db 0dh,0ah,'Column not found!$'
sPress db 0dh,0ah,0ah,'Press any key for exit$'

N equ 5 ;размерность матрицы

.data?
matrix dw N*N dup(?) ;матрица 5х5
;буфер для ввода числовой строки (для функции 0ah)
sNum db ? ;максимальный размер буфера
sCount db ? ;реальный размер строки
sBuf db 80 dup (?) ;сама строка

.code
start:
mov ax, _DATA ;настроим сегментные регистры
mov ds, ax ;на сегмент данных
mov es, ax

call GetMatrix ;введем матрицу

lea dx, sSource ;заголовок
call PrintMatrix ;выведем исходную матрицу

call GetResult ;найдем то, что требуется
cmp ax, -1 ;-1 значит не найдено
je not_found

inc ax ;сделаем счет с 1
push ax ;сохраним номер столбца
lea dx, sColumn
mov ah, 9
int 21h ;выведем строку
pop ax ;и число
call PrintNum
jmp print_press ;на "Press any key"
not_found:
lea dx, sNotFound ;не найдено
mov ah, 9
int 21h
print_press:
lea dx, sPress ;Press any key
mov ah, 9
int 21h

mov ah, 0 ;ждем "any key"
int 16h

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

PrintMatrix proc ;вывод матрицы NxN
mov ah, 9
int 21h ;вывод заголовока из dx

lea si, matrix ;адрес массива
mov cx, N ;число строк
PrintRowLoop: ;вывод строк
push cx ;сохраним счетчик строк
mov cx, N ;чисо столбцов
PrintColLoop: ;вывод одной строки
lodsw ;очередное значение
call PrintNum ;вывод числовой строки
mov dl, 9 ;разделим табуляцией
int 21h ;ah = 2
loop PrintColLoop
mov dl, 0dh ;переход на новую строку
int 21h
mov dl, 0ah
int 21h
pop cx ;восстановим счетчик строк
loop PrintRowLoop
ret
PrintMatrix endp

PrintNum proc ;вывод беззнакового числа из ax
push cx ;сохраним счетчик колонок
mov bx, 10 ;будем делить на 10
xor cx, cx ;счетчик цифр
DivLoop:
xor dx, dx ;готовимся к делению dx:ax / bx
div bx ;ax - частное, dx - остаток=очередной младшей цифре
push dx ;сохраним цифру в стеке
inc cx ;посчитаем
test ax, ax ;продолжим, пока не 0
jnz DivLoop
mov ah, 2 ;функция вывода
PrintLoop: ;будем выводить в обратном порядке,
; начиная со старшей шифры
pop dx ;восстановим очередной разряд
or dl, '0' ;превратим в символ
int 21h ;выведем
loop PrintLoop
pop cx
ret
PrintNum endp

GetMatrix proc ;ввод матрицы
lea dx, sMatrix
mov ah, 9
int 21h ;приглашение на ввод элементов матрицы

lea di, matrix ;адрес массива

mov ax, N ;адрес за массивом (для контроля конца)
mul ax
shl ax, 1
add ax, offset matrix
mov bp, ax ;сохраним для сравнения на конец
GM_ask:
mov ah, 2
mov dl, 0ah
int 21h ;переход на новую строку

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

GM_next:
cmp di, bp ;массив заполнен?
je GM_ret

call stoi ;[si] -> ax
jcxz GM_ask ;дошли до конца строки?
stosw ;сохраняем
jmp GM_next ;на следующее число в строке
GM_ret:
ret
GetMatrix endp

GetResult proc ;поиск максимального столбца с двуразрядными числами
mov di, -1 ;считаем пока, что не найдено
xor bx, bx ;адрес первого элемента первого столбца
mov cx, N ;количество столбцов

SearchAllColumnLoop: ;цикл по столбцам
push cx ;сохраним счетчик столбцов
xor si, si ;смещение первого элемента в столбце
mov cx, N ;количество строк в столбце
SearchOneColumnLoop: ;цикл по строкам в столбце
mov ax, matrix[bx+si] ;очередной элемент
cmp ax, 10 ;проверим на 10<=ax<=99 (на двузначность)
jb SearchAllColumnNext ;не попадает - на следующий столбец
cmp ax, 99
ja SearchAllColumnNext ;не попадает - на следующий столбец
add si, 2*N ;переход на следующую строку столбца
loop SearchOneColumnLoop ;цикл по элементам столбца
mov di, bx ;прошли весь столбец, значит, все элементы - двузначные
shr di, 1 ;запоминаем его индекс,
; разделив на 2 двубайтное смещение
SearchAllColumnNext: ;переходим на следующий столбец
pop cx ;восстановим счетчик столбцов
inc bx ;переходим на следующий столбец
inc bx
loop SearchAllColumnLoop ;по всем колонкам
mov ax, di ;результат поиска вернем в ax
ret
GetResult endp

;функция преобразовывает числовую строку в число
;преобразование заканчивается по любому разделителю или концу строки (0dh)
;признаком конца строки является cx = 0
stoi proc ;преобразование строки [si] в беззнаковое число AX
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
ret
stoi endp

end start[/code]
5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
19.05.2013, 23:33
общий
Спасибо большое)
1 вопрос - можно ли в программе, изменив переменную N вводить матрицу другой размерности?
давно
Посетитель
7438
7205
20.05.2013, 10:49
общий
Если имеете в виду, просто поменять в тексте программы, то без проблем.
А если вводить с клавиатуры, то надо будет немного переделать...
Кстати, сейчас N - не переменная, а константа..
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа