Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обработка массива, поиск MAX элемента 
:(
    Опции темы
bncom
Дата 15.4.2007, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 2.11.2005

Репутация: нет
Всего: 1



Здравствуйте!

Вот код, который находит максимальный элемент в массиве.

Код

.MODEL SMALL

;----------Сегмент стека------------
STACKSG SEGMENT PARA STACK 'stack'
        DB      256  DUP(?)  
STACKSG ENDS
;-----------------------------------

;----------Сегмент данных-----------
DATASG  SEGMENT PARA  'data'
NUMBER  DW     5
MASSIV  DW     0,3,-6,34,10    
REZ     DB     ?
DATASG  ENDS
;----------------------------------

;----------Сегмент кода------------
CODESG  SEGMENT PARA 'Code'
        ASSUME  CS:CODESG, DS:DATASG, SS:STACKSG 

MAIN    PROC    FAR

    PUSH    DS           ; Подготовка к
    SUB     AX,AX         ; возврату в
    PUSH    AX         ; ОС

    MOV    AX, DATASG    ; Настраиваем регистр DS на
    MOV    DS,AX        ; сегмент данных

    MOV     AX,NUMBER    ; 
    LEA     SI,MASSIV    ; Загружаем адрес MASSIV в регистр индекса источника SI
    PUSH    SI        ; Заносим адрес начала массива к стек
    PUSH    AX        ; Заносим количество элементов в стек
    CALL    MAX_EL        ; Вызов подпрограммы поиска максимального элемента
    MOV    REZ,AX        ; Заносим результат в REZ
    ;MOV     BX,AX
    ;MOV     AL,BX
    ;MOV     REZ,AL
    RET              ; Завершение работы
MAIN    ENDP

MAX_EL    PROC    NEAR
    PUSH    BP        ; Сохраняем старое значение указателя базы кадров стека BP
    MOV    BP,SP        ; Ставим указатель BP на указатель стека SP
    MOV    CX,[BP+4]    ; Количество элементов массива
    MOV    SI,[BP+6]    ; Адрес массива
    MOV    AX,[SI]        ; Максимальный элемент массива
For:    MOV     BX,[SI]        ; Помещаем в регистр BX элемент массива
    CMP    BX,AX        ; Сравниваем текущий элемент с максимальным
    JS      End_if        ; Если BX < MAX, то переходим к метке End_if
    MOV     AX,BX        ; Иначе AX=BL
End_if: ADD     SI,2        ; Переходим к следующему элементу массива
    LOOP    For        ; CX-=1, если CX!=0, то переходим к метке For
    POP    BX        ; Восстанавливаем значение BP
    RET    4
MAX_EL    ENDP

CODESG  ENDS
        END    MAIN


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

Помогите пожалуйтса....

Это сообщение отредактировал(а) bncom - 15.4.2007, 19:45
--------------------
"Мы никогда не живем, мы лишь надеемся, что будем жить." Вольтер 
PM MAIL   Вверх
JAPH
Дата 15.4.2007, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: 5
Всего: 23



Sorry, а как вы собираетесь запихнуть 16-битный элемент массива в 8-битный AL?!
В строке 54 POP BP smile


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
bncom
Дата 16.4.2007, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 2.11.2005

Репутация: нет
Всего: 1



Цитата

Sorry, а как вы собираетесь запихнуть 16-битный элемент массива в 8-битный AL?!
Ну вот такое задание, что поделаешь...
Так может быть кое-что тогда изменить надо?
--------------------
"Мы никогда не живем, мы лишь надеемся, что будем жить." Вольтер 
PM MAIL   Вверх
JAPH
Дата 16.4.2007, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: 5
Всего: 23



Элементы массива обязательно word? Сделайте их DB ..., поиск максимума перепишите с использованием 8-битных регистров.


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
bncom
Дата 16.4.2007, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 2.11.2005

Репутация: нет
Всего: 1



JAPH, сделал как вы подсказали - в результате получается какой-т обесконечный цикл...

Код

.MODEL SMALL

;----------Сегмент стека------------
STACKSG SEGMENT PARA STACK 'stack'
        DB      256  DUP(?)  
STACKSG ENDS
;-----------------------------------

;----------Сегмент данных-----------
DATASG  SEGMENT PARA  'data'
NUMBER  DB     5
MASSIV  DB     0,3,-6,34,10    
REZ     DB     ?
DATASG  ENDS
;----------------------------------

;----------Сегмент кода------------
CODESG  SEGMENT PARA 'Code'
        ASSUME  CS:CODESG, DS:DATASG, SS:STACKSG 

MAIN    PROC    FAR

    PUSH    DS           ; Подготовка к
    SUB     AX,AX         ; возврату в
    PUSH    AX         ; ОС

    MOV    AX, DATASG    ; Настраиваем регистр DS на
    MOV    DS,AX        ; сегмент данных

    MOV     AL,NUMBER    ; 
    LEA     SI,MASSIV    ; Загружаем адрес MASSIV в регистр индекса источника SI
    PUSH    SI        ; Заносим адрес начала массива к стек
    PUSH    AX        ; Заносим количество элементов в стек
    CALL    MAX_EL        ; Вызов подпрограммы поиска максимального элемента
    MOV    REZ,AL        ; Заносим результат в REZ
    RET              ; Завершение работы
MAIN    ENDP

MAX_EL    PROC    NEAR
    PUSH    BP        ; Сохраняем старое значение указателя базы кадров стека BP
    MOV    BP,SP        ; Ставим указатель BP на указатель стека SP
    MOV    CX,[BP+4]    ; Количество элементов массива
    MOV    SI,[BP+6]    ; Адрес массива
    MOV    AL,[SI]        ; Максимальный элемент массива
For:    MOV     BL,[SI]        ; Помещаем в регистр BX элемент массива
    CMP    BL,AL        ; Сравниваем текущий элемент с максимальным
    JS      End_if        ; Если BX < MAX, то переходим к метке End_if
    MOV     AL,BL        ; Иначе AX=BL
End_if: ADD     SI,2        ; Переходим к следующему элементу массива
    LOOP    For        ; CX-=1, если CX!=0, то переходим к метке For
    POP    BP        ; Восстанавливаем значение BP
    RET    4
MAX_EL    ENDP

CODESG  ENDS
        END    MAIN


У меня в массиве всего 5 элементов, а цикл проходит более 50 раз и дальше...


--------------------
"Мы никогда не живем, мы лишь надеемся, что будем жить." Вольтер 
PM MAIL   Вверх
JAPH
Дата 16.4.2007, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: 5
Всего: 23



Цитата
Код
MOV  AL, NUMBER
...
PUSH AX

А в AH у вас что? Остаток DSEG?
Вставьте XOR AH, AH.
Да, и ещё INC SI в строке 49.


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
bncom
Дата 17.4.2007, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 2.11.2005

Репутация: нет
Всего: 1



Опять же такая проблема (подправил как вы подсказали).

Код

.MODEL SMALL

;----------Сегмент стека------------
STACKSG SEGMENT PARA STACK 'stack'
        DB      256  DUP(?)  
STACKSG ENDS
;-----------------------------------

;----------Сегмент данных-----------
DATASG  SEGMENT PARA  'data'
NUMBER  DB     5
MASSIV  DB     0,3,-6,34,10    
REZ     DB     ?
DATASG  ENDS
;----------------------------------

;----------Сегмент кода------------
CODESG  SEGMENT PARA 'Code'
        ASSUME  CS:CODESG, DS:DATASG, SS:STACKSG 

MAIN    PROC    FAR
     PUSH    DS            ; Подготовка к
     SUB     AX,AX          ; возврату в
     PUSH    AX          ; ОС

     MOV     AX, DATASG     ; Настраиваем регистр DS на
     MOV     DS,AX         ; сегмент данных

     MOV     AL,NUMBER     ; 
     LEA     SI,MASSIV     ; Загружаем адрес MASSIV в регистр индекса источника SI
     PUSH    SI        ; Заносим адрес начала массива к стек
     XOR    AX,AX
     PUSH    AX         ; Заносим количество элементов в стек
     
     CALL    MAX_EL         ; Вызов подпрограммы поиска максимального элемента
     MOV     REZ,AL         ; Заносим результат в REZ
     RET               ; Завершение работы
MAIN    ENDP

MAX_EL  PROC    NEAR
     PUSH    BP         ; Сохраняем старое значение указателя базы кадров стека BP
     MOV     BP,SP      ; Ставим указатель BP на указатель стека SP
     MOV     CX,[BP+4]    ; Количество элементов массива
     MOV     SI,[BP+6]     ; Адрес массива
     MOV     AL,[SI]         ; Максимальный элемент массива
For:    MOV     BL,[SI]         ; Помещаем в регистр BX элемент массива
     CMP     BL,AL         ; Сравниваем текущий элемент с максимальным
     JS      End_if         ; Если BX < MAX, то переходим к метке End_if
     MOV     AL,BL         ; Иначе AL=BL
     INC    SI 
End_if: ADD     SI,2         ; Переходим к следующему элементу массива
     LOOP    For         ; CX-=1, если CX!=0, то переходим к метке For
     POP     BP         ; Восстанавливаем значение BP
     RET     4
MAX_EL  ENDP

CODESG  ENDS
        END    MAIN


Когда начинаю трассировать в ручном режиме - как буд-то все нормально. Максимальный элемент заносится в AX (хотя, по-идеи он должен быть в AL, но я не знаю где смотреть AL в Turbo Debbager'е), а дальше опять какой-т обесконечный цикл...
 smile 

Можетя я что-то не туда вставляю?

 smile 
--------------------
"Мы никогда не живем, мы лишь надеемся, что будем жить." Вольтер 
PM MAIL   Вверх
sgi1981
Дата 17.4.2007, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 16.3.2006

Репутация: 2
Всего: 10



Код

.MODEL SMALL
;----------Сегмент стека------------
STACKSG SEGMENT PARA STACK 'stack'
        DB      256  DUP(?)  
STACKSG ENDS
;-----------------------------------
;----------Сегмент данных-----------
DATASG  SEGMENT PARA  'data'
NUMBER  DW     5
MASSIV  DB     0,3,-6,34,10    
REZ     DB     ?
DATASG  ENDS
;----------------------------------
;----------Сегмент кода------------
CODESG  SEGMENT PARA 'Code'
        ASSUME  CS:CODESG, DS:DATASG, SS:STACKSG 
MAIN    PROC    FAR
    PUSH    DS           ; Подготовка к
    SUB     AX,AX         ; возврату в
    PUSH    AX         ; ОС
    MOV    AX, DATASG    ; Настраиваем регистр DS на
    MOV    DS,AX        ; сегмент данных
    MOV     AX,NUMBER    ; 
    LEA     SI,MASSIV    ; Загружаем адрес MASSIV в регистр индекса источника SI
    PUSH    SI        ; Заносим адрес начала массива к стек
    PUSH    AX        ; Заносим количество элементов в стек
    CALL    MAX_EL        ; Вызов подпрограммы поиска максимального элемента
    MOV    REZ,AL        ; Заносим результат в REZ
    RET              ; Завершение работы
MAIN    ENDP

MAX_EL    PROC    NEAR
    PUSH    BP        ; Сохраняем старое значение указателя базы кадров стека BP
    MOV    BP,SP        ; Ставим указатель BP на указатель стека SP
xor dx, dx;обнулить регистры для исключения влияния старших частей регистров
xor ax, ax;
    MOV    CX,[BP+4]    ; Количество элементов массива
    test cx, cx;предотвращение 
    jz @error55;ошибки при количестве элементов массива = 0
    MOV    SI,[BP+6]    ; Адрес массива
    MOV    DL,[SI]        ; Максимальный элемент массива
dec cx;количество остальных элементов массива на 1 меньше
jcxz @error55;если массив состоит из одного элемента - обходим цикл
cld;выполнение цепочечных команд с увеличением адреса адресных регистров
inc si;переходим на следующий элемент массива
For:;цикл
lodsb; Помещаем в регистр AL элемент массива и смещает указатель si на один байт 
;(ah и dh  равны 0)
cmovl dx, ax;если dx меньше ax - помещает dx=ax
loop  For;
@error55:
mov ax, dx;вернуть максимальный элемент в ax (на самом деле эффективно записывается al)
    POP    BX        ; Восстанавливаем значение BP
    RET    4
MAX_EL    ENDP
CODESG  ENDS
        END    MAIN



--------------------
Тело в нашем пространстве - есть часть пространства, в которой пространство обладает дисторсией относительно внешнего пространства.
PM MAIL   Вверх
bncom
Дата 18.4.2007, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 2.11.2005

Репутация: нет
Всего: 1



sgi1981, спасибо большое!
У вас даже лучше получилось: предусмотрели "защиту" от дурака как говорят...

Но на 49 строчке (cmovl dx, ax)у меня выдает ошибку.

Ошибка в команде видимо, т.к. CMOVL делает пересылку значения источника в приемник, если флаги SF<>OF.

Или еще в чем-то....
--------------------
"Мы никогда не живем, мы лишь надеемся, что будем жить." Вольтер 
PM MAIL   Вверх
JAPH
Дата 18.4.2007, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: 5
Всего: 23



Цитата
Можетя я что-то не туда вставляю?

Конечно, не туда! Точнее, не то smile
XOR AH, AH, а не XOR AX, AX!
INC SI вместо ADD SI, 2.

Цитата
где смотреть AL в Turbo Debbager'е

AL - младший байт AX. AX вы знаете где. Две младшие его цифры и есть AL; две старшие, кстати, AH.

Цитата
Или еще в чем-то....

В том, что CMOVxx появилась в Pentium Pro.

Код

; А зачем .MODEL? Мы же полностью определяем сегменты
        .186
STACKSG SEGMENT PARA STACK 'stack'
        DB      256  DUP(?)
STACKSG ENDS
DATASG  SEGMENT PARA  'data'
NUMBER  DW     5
MASSIV  DB     0,3,-6,34,10
REZ     DB     ?
DATASG  ENDS
CODESG  SEGMENT PARA 'Code'
        ASSUME  CS:CODESG, DS:DATASG, SS:STACKSG
MAIN    PROC    FAR
        PUSH    DS
        PUSH    0
        MOV     AX, DATASG
        MOV     DS, AX
        PUSH    offset MASSIV
        PUSH    NUMBER
        CALL    MAX_EL
        MOV     REZ, AL
        RET
MAIN    ENDP
MAX_EL  PROC    NEAR
        PUSH    BP
        MOV     BP, SP
        MOV     CX, [BP+4]
        MOV     SI, [BP+6]
        MOV     AL, [SI]
For:    DEC     CX
        JZ      End_for
        CMP     AL, [SI]
        JG      End_if
        MOV     AL, [SI]
End_if: INC     SI
        JMP     For
End_for:POP     BP
        RET     4
MAX_EL  ENDP
CODESG  ENDS
        END    MAIN


Это сообщение отредактировал(а) JAPH - 18.4.2007, 19:52


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
sgi1981
Дата 19.4.2007, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 16.3.2006

Репутация: 2
Всего: 10



To bncom:
напиши в самом начале директиву
.586p


--------------------
Тело в нашем пространстве - есть часть пространства, в которой пространство обладает дисторсией относительно внешнего пространства.
PM MAIL   Вверх
bncom
Дата 19.4.2007, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 2.11.2005

Репутация: нет
Всего: 1



Все сделал - все получилось! =)

Большое всем спасибо!  smile 
--------------------
"Мы никогда не живем, мы лишь надеемся, что будем жить." Вольтер 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для начинающих"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для начинающих | Следующая тема »


 




[ Время генерации скрипта: 0.1001 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.