Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Помогите найти максимальный элемент в массиве.  (Прочитано 16025 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Dimmon
Гость
« : 14-01-2006 14:02 » 

У меня задание, где нужно ввести массив и вывести его на экран. Но теперь пеподу понадобилось, чтоб еще найти максимальный элемент и заменить его на 1 и вывести на экран массив с замененным элементом. Я ввод/вывод еле сделал (и то не без дорых людей). Я как найти и заменить вообще не знаю. С ума сойти...
Все время с++ изучали, а тут вот и ассемблер теперь нужно.
Помогите пожалуйста, если можете.

Код:
MODEL SMALL            ;Малая модель памяти cs<>ds,cs<>ss 
STACK 100h            ;100h памяти под сегмент
LOCALS @@            ;Метки с префиксом @@ счит. локальными
mSize   equ 3            ;Размер матрицы


;--------------------------------------------------
; Сегмент данных
;--------------------------------------------------
data   segment                       ;Начало сегмента данных
 matrix   db mSize*mSize dup(?)
 prompt2 db 'Массив:','$'      ;DOS-строка 'числа...'
 prompt3 db 'Введите число:','$'   ;DOS-строка 'введите...'
 endl    db 13,10,'$'         ;DOS-строка - перевод на след. строчку

 nbSize    db ?            ;Заголовок под буфер ввода
 nbInp    db ?
 buf    db 6 dup(?)         ;DOS-строка буфер для числа
    db '$'
data   ends               ;Конец сегмента данных

;--------------------------------------------------
; Сегмент кода
;--------------------------------------------------
code    segment            ;Начало сегмента
   assume cs:code,ds:data      ;Обещаем выставить cs=code,ds=data
 start:               ;Точка входа в программу
   mov   ax,data         ;ds=data (Инициализируем DS сегмент)
   mov   ds,ax

   mov   cx,mSize*mSize              ;cx=кол-ву эл-тов матрицы
   mov   si,OFFSET matrix      ;ds:si указывает на матрицу
   call   doEnterMatrix               ;Вызываем процедуру заполнения матрицы

   call   doClearScreen               ;Очищаем экран

   
   mov   si,OFFSET matrix      ;ds:si указывает на матрицу
   mov   cx,mSize*mSize               ;cx = кол-ву элементов в матрице
   
      ;Вызываем вывод перевода строки

   mov   si,OFFSET prompt2      ;ds:si указывает на prompt2
   call   doPrintStr         ;Печатаем на экране строку prompt2
   mov   cx,mSize*mSize              ;cx = кол-ву элементов в матрице
   mov   si,OFFSET matrix      ;ds:si теперь указывает на матрицу
   call   doOut                 ;Вызываем вывод матрицы
   mov   si,OFFSET endl               ;ds:si указывает на симв. перев. строки
   call   doPrintStr         ;Вызываем вывод перевода строки

   call   doWaitAKey         ;Ожидаем нажатие клавиши

   mov   ax,4C00h         ;Выходим из программы -
   int   21h            ; прерывание 21h(DOS),ф-я 4Ch

;--------------------------------------------------
; doEnterMatrix - процедура ввода
;--------------------------------------------------

 doEnterMatrix   proc near                       ;Начало описания процедуры
   push   es            ;Сохраняем es в стеке
   push   di            ;Сохраняем di в стеке
   push   si            ;Сохраняем si в стеке
   push   cx            ;Сохраняем cx в стеке
   push   ax            ;Сохраняем ax в стеке
   pushf               ;Сохраняем флаги в стеке

   mov   byte ptr ds:[nbSize],5   ;Макс. кол-во символов, кот.можно ввести

   mov   ax,ds            ;ax=ds
   mov   es,ax            ;es=ax=ds
   mov   di,si            ;si=di
   cld               ;Сбрасываем флаг направления (вперёд)
@@lAgain:               ;Начало цикла
   call   doClearScreen               ;Вызываем очистку экрана
   mov   si,OFFSET prompt3      ;ds:si указывает на строку prompt3
   call   doPrintStr         ;Вызываем проц. вывода строки на экран

   mov   ah,0Ah                 ;ah=0Ah
   mov   dx,OFFSET nbSize      ;ds:dx указывает на буфер для ввода
   int   21h            ;Прерывание 21h(DOS) ввод строки
   push   cx            ;Сохраняем cx в стеке
   xor   ch,ch            ;ch=0 (быстрое обнуление)
   mov   cl,byte ptr ds:[nbInp]           ;cl=кол-ву введённых символов
   mov   si,OFFSET buf              ;ds:si указывает на буфер ввода
   call   doStr2Byte         ;Вызвать преобразование строки в число
   pop   cx            ;Восстановить cx из стека
   
   cld               ;Сбрасываем флаг направления(вперёд)
   stosb               ;Сохраняем полученное число в матрицу
   loop   @@lAgain         ;Конец цикла

   popf               ;Восстанавливаем флаги из стека
   pop   ax            ;Восстанавливаем ax из стека
   pop   cx            ;Восстанавливаем cx из стека
   pop   si            ;Восстанавливаем si из стека
   pop   di            ;Восстанавливаем di из стека
   pop   es            ;Восстанавливаем es из стека
   ret               ;Выходим из процедуры
 doEnterMatrix  endp                     ;Конец описания процедуры

;--------------------------------------------------
; doEnterMatrix - процедура вывода
;--------------------------------------------------
 doOut   proc near                       ;Начало описания процедуры
   push   si         ;Сохраняем si в стеке
   push   dx         ;Сохраняем dx в стеке
   push   cx         ;Сохраняем cx в стеке
   push   bx         ;Сохраняем bx в стеке
   push   ax         ;Сохраняем ax в стеке
   pushf            ;Сохраняем флаги в стеке

   xor   ah,ah         ;ah=0 (верхняя часть ax)
   cld            ;Сбрасываем флаг направления (вперёд)
  @@lNext:                              ;Начало цикла
   lodsb            ;al=следующему эл-ту матрицы
   
   mov   bx,si         ;Сохраняем si в bx (bx=si)
   mov   dx,cx         ;Сохраняем cx в dx (dx=cx)
   mov   cx,LENGTH buf           ;cx = размеру буфера
   mov   si,OFFSET buf           ;ds:si указывает на начало буфера
   call   doWord2Str      ;Вызываем преобразование числа в строку
   mov   cx,dx         ;Восстанавливаем cx из dx (cx=dx)
   mov   si,OFFSET buf           ;ds:si указывает на буфер (строку)
   call   doPrintStr      ;Выводим буфер (строку)(число)
   mov   si,bx         ;Восстанавливаем si из bx (si=bx)

  @@lSkip:            ;Метка @@lSkip
   loop   @@lNext      ;Конец цикла

   popf            ;Восстанавливаем из стека флаги
   pop   ax         ;Восстанавливаем из стека ax
   pop   bx         ;Восстанавливаем из стека bx
   pop   cx         ;Восстанавливаем из стека cx
   pop   dx         ;Восстанавливаем из стека dx
   pop   si         ;Восстанавливаем из стека si
   ret            ;Выходим из процедуры
 doOut   endp         ;Конец описания процедуры

;--------------------------------------------------
; doClearScreen - процедура очистки экрана
;--------------------------------------------------
   doClearScreen   proc near       ;Начало описания процедуры
   push   ax         ;Сохраняем ax в стеке
   pushf            ;Сохраняем флаги

   mov   ax,0003h      ;ah = 0, al = 03 (номер видео режима)
   int   10h         ;Прерыване 10h(BIOS) устан. вид.режима

   popf            ;Восстанавливаем из стека флаги
   pop   ax         ;Восстанавливаем из стека ax
   ret            ;Выходим из процедуры
    doClearScreen   endp      ;Конец описания процедуры

;--------------------------------------------------
; doWaitAKey - процедура ожидания клавиши
;--------------------------------------------------
 doWaitAKey   proc near               ;Начало описания процедуры
   push   ax         ;Сохраняем ax в стеке
   pushf            ;Сохраняем флаги в стеке

   xor   ah,ah         ;ah=0 (быстрое обнуление)
   int   16h         ;Прерывание 16h(BIOS) читаем клавишу

   popf            ;Восстанавливаем из стека флаги
   pop   ax                      ;Восстанавливаем из стека ax
 doWaitAKey   endp         ;Конец описания процедуры

;--------------------------------------------------
; doPrintStr - Вывод DOS строки на экран
;--------------------------------------------------
 doPrintStr   proc near               ;Начало описания процедуры
   push   dx         ;Сохраняем dx в стеке
   push   ax         ;Сохраняем ax в стеке
   pushf            ;Сохраняем флаги в стеке

   mov   ah,09h               ;ah = 09h
   mov   dx,si         ;dx = si
   int   21h         ;Прерывание 21h(DOS) выв. строки

   popf            ;Восстанавливаем из стека флаги
   pop   ax         ;Восстанавливаем из стека ax
   pop   dx         ;Восстанавливаем из стека dx
   ret            ;Выходим из процедуры
 doPrintStr   endp         ;Конец описания процедуры

;--------------------------------------------------
; doWord2Str - Перевод числа в строку
;--------------------------------------------------
 doWord2Str   proc near               ;Начало описания процедуры
   push   si         ;Сохраняем si в стеке
   push   dx         ;Сохраняем dx в стеке
   push   cx         ;Сохраняем cx в стеке
   push   bx         ;Сохраняем bx в стеке
   push   ax         ;Сохраняем ax в стеке
   pushf            ;Сохраняем в стеке флаги

   mov   dl,al         ;Сохраняем al в dl (dl=al)
   mov   al,' '              ;al = пробелу
   call   doFillBuf      ;Заполняем буфер пробелами
   mov   al,dl         ;Восстанавливаем al (al=dl)

   test   ah,10000000b   ;ax<0? (первый бит установлен?)
   jz   @@skipNeg      ;Нет => @@skipNeg
   neg   ax         ;ax=-ax
   mov   byte ptr ds:[si],'-'   ;Записываем в буфер симв. '-'
@@skipNeg:
   dec   cx         ;Уменьшаем cx (место под знак)
   add   si,cx         ;ds:si указывает на конец буфера
   mov   bx,10         ;bx=10 (будем делить на 10)
@@lNext:                                ;Начало цикла
   xor   dx,dx         ;Обнуляем остаток от деления (dx=0)
   div   bx         ;Делим ax на bx (ax=ax/10, dx=остаток)
   add   dl,'0'         ;Прибавляем к dl символ '0'
   mov   byte ptr ds:[si],dl   ;Сохраняем в буфере
   test   ax,ax         ;ax = 0? (делить имеет смысл?)
   jz   @@lExit         ;нет => выход из цикла
   dec   si         ;Сдвигаемся по буферу
   loop   @@lNext         ;Следующий шаг

@@lExit:
   popf            ;Восстанавливаем из стека флаги
   pop   ax         ;Восстанавливаем из стека ax
   pop   bx         ;Восстанавливаем из стека bx
   pop   cx         ;Восстанавливаем из стека cx
   pop   dx                      ;Восстанавливаем из стека dx
   pop   si         ;Восстанавливаем из стека si
   ret            ;Выходим из процедуры
 doWord2Str   endp         ;Конец описания процедуры

;--------------------------------------------------
; doStr2Byte - Перевод строки в байт
;--------------------------------------------------
 doStr2Byte   proc near               ;Начало описания процедуры
   push   si         ;Сохраняем si в стеке
   push   dx         ;Сохраняем dx в стеке
   push   cx         ;Сохраняем cx в стеке
   push   bx         ;Сохраняем bx в стеке

   mov   bx,cx         ;Сохраняем cx в bx
   cld            ;Сбрасываем флаг направления(вперёд)
   lodsb            ;Читаем первый символ
   cmp   al,'-'              ;Сравниваем его с символом '-'
   jne   @@lSkip              ;Если не равен => lSkip
   dec   cx         ;Иначе уменьшаем счётчик символов
   dec   bx         ;И сохранённый тоже
@@lNext:            ;Начало цикла (проверка строки)
   lodsb            ;Загружаем следующий символ в al
@@lSkip:
   cmp   al,'0'              ;Сравниваем его с '0'
   jb   @@lExitE      ;Если меньше,то выходим из цикла(ошибка)
   cmp   al,'9'               ;Сравниваем его с '9'
   ja   @@lExitE      ;Если больше,то выходим из цикла(ошибка)
   loop   @@lNext              ;Конец цикла
   
   dec   si         ;Передвигаем si на последний символ
   mov   cx,bx         ;Восстанавливаем cx из bx
   std            ;Устанавливаем флаг переноса (назад)
   mov   dx,0A01h      ;dh=10, dl=1 (коэфф.умножения, множит.)
   xor   bx,bx         ;bx=0 (сумма - быстрое обнуление)
@@lNextD:            ;Начало цикла
   lodsb            ;Считываем предыдущий символ
   sub   al,'0'              ;Преобразуем символ в число
   mul   dl         ;Умножаем его на dl (1,10,100...)
   test   ah,ah         ;Проверяем вышел ли он за пределы байта
   jnz   @@lExitE      ;Если вышел - выходим из цикла (ошибка)
   add   bx,ax         ;bx=bx+ax (суммируем)
   mov   al,dl         ;al=dl (готовимся к умножению множителя=)
   mul   dh         ;умножаем
   mov   dl,al         ;dl=множителю (1,10,100...)
   loop   @@lNextD      ;Конец цикла
   
   lodsb            ;Дочитываем символ
   cmp   al,'-'              ;Сравниваем его с '-'
   jne   @@lSkipN      ;Если нет =>lSkipN
   neg   bx         ;Иначе bx=-bx
@@lSkipN:
   mov   ax,bx         ;ax=bx=числу
   clc            ;Сбрасываем флаг переноса (нет ошибки)
   jmp   @@lExit              ;Выходим

@@lExitE:
   stc            ;Устанавливаем флаг переноса(ошибка)
@@lExit:
   pop   bx         ;Восстанавливаем из стека bx
   pop   cx         ;Восстанавливаем из стека cx
   pop   dx                      ;Восстанавливаем из стека dx
   pop   si         ;Восстанавливаем из стека si
   ret            ;Выходим из процедуры
 doStr2Byte endp         ;Конец описания процедуры

;--------------------------------------------------
; doFillBuf - Заполняет буфер заданным значением
;--------------------------------------------------
 doFillBuf   proc near               ;Начало описания процедуры
   push   es         ;Сохраняем es в стеке
   push   di         ;Сохраняем di в стеке
   push   cx         ;Сохраняем сx в стеке
   push   bx         ;Сохраняем bx в стеке
   
   mov   bx,ds         ;bx = ds
   mov   es,bx         ;es = bx = ds
   mov   di,si         ;di = si
   cld            ;Сбрасываем флаг направления (вперёд)
   rep   stosb         ;Пишем сод. ax, cx раз в строку es:di

   pop   bx         ;Восстанавливаем из стека bx
   pop   cx         ;Восстанавливаем из стека cx
   pop   di         ;Восстанавливаем из стека di
   pop   es         ;Восстанавливаем из стека es
   ret            ;Выходим из процедуры
 doFillBuf   endp              ;Конец описания процедуры

code   ends                            ;Конец сегмента кода
end   start                       ;Конец программы
« Последнее редактирование: 15-12-2007 16:23 от Алексей1153++ » Записан
andrystepa
Помогающий

ru
Offline Offline

« Ответ #1 : 26-12-2006 19:29 » new

А в чем, собственно, проблема? Массив ты заполнил - он находится по адресу matrix. Загрузи в cx размер_массива-1, ax первый элемент массива (это будет первый максимум), загрузи в bx  второй элемент ( mov bx, matrix[размер_массива - cx]) и сравни их. Если ax below bx, замени ax на bx, и где нибудь сохрани индекс (размер_массива - cx) - например в стеке. Затем dec cx и jnz на начало цикла. После цикла в стеке останется индекс максимального значения. Туда, то есть в matrix+индекс и записывай 1.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines