Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Assembler] Сортировка массива 
V
    Опции темы
seven65
Дата 1.12.2006, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Написать программу на языке Ассемблер, в которой осуществляется обработка исходного массива (10 – 15 элементов) и формирование массива результата. Размерность элементов исходного массива и массива результата – WORD.
Действия для предварительной обработки элементов исходного массива выбирается из таблицы 1.
Условия поэлементного формирования массива результата из таблицы 2.
Выбор способов адресации выбирается из таблицы 3.

1)
Способ обработки:
В исходном массиве переставить элементы так, чтобы они располагались в следующем порядке.  
Отрицательные и положительные элементы исходного массива в порядке их расположения меняются местами.

2)
Условия формирования массива результата.
Элемент исходного массива помещается в массив результата если его значение:
больше среднего арифметического наибольшего и последнего элемента исходного массива.

После отладки программы изменить е+- для обработки данных  размерности DWORD.

3)
Способ адресации.
Обработка исходного массива - индексная.
Формирование массива результата - базовая. 
PM MAIL   Вверх
anwe
Дата 9.12.2006, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



По многочисленным просьбам сделал.
Программка делает то, что просил. Элементы исходного массива заданы произвольно так же, как и их количество.
Среднее арифметическое вычислено с использованием целочисленной арифметики, вернее используется следующее свойство: среднее арифметическое двух целых чисел будет либо целым числом либо иметь дробную часть 5/10.
В условии задачи написано, чтобы элементы нового массива были больше этого среднего арифметического. Поэтому целочисленной арифметики хватает.
Пусть при делении на 2 получил 5,5, что в целочисленной арифметике означает частное равно 5 плюс какой-то остаток. Значит для удовлетворения условию задачи элемент должет быть просто больше 5 (ведь 6>5,5), значит применяемое условие будет "больше". Но это для положительных чисел. Для отрицательных не так.
Пусть среднее арифметическое равно -5,5. Частное равно -5. Если возмешь -4, это будет верно, но также и -5>-5,5. Значит в случае с отрицательными числами надо брать не только большие, чем частное, но и числа равные частному. Значит применяемое условие будет "больше или равно".
Чтобы такой отбор сделать в одном цикле, то есть использовать одно условие, надо "оттянуть" частное, если оно отрицательное, на 1 влево, то есть уменьшить его. Для этого примера получим частное -6. Тогда одно условие "больше" можно применить и для отрицательных и для положительных чисел. Это и делает часть кода
Код

    cmp    sign,1000000000000000b
    jne    l4
    dec    ax
l4:

И последнее. Для преобразования исходного массива (и нового соответственно) в размер двойных слов надо:
1. Расширить все регистры размерности слова до двойного путем дабавления е.
2. Изменить 2->4.
3. Изменить 1->2, но только в делении. В командах inc и dec ничего не менять!
4. При определении знака добить еще 16 нулей.
5. Переделать блоки вывода массивов под размерность двойных слов (это еще одно сохранение, сдиг и восстановлени выводимого символа по подобию, как это уже сделано).
6. Заменить размерности массива, нового массива и знаков (не длинн).

Сам код:
Код

    .model tiny
    .code
    .386
    org 100h
start:
    movzx    ecx,len        ;для цикла заносим длину массива
    shr    ecx,1        ;так как длина в словах делим на 2
    dec    cl        ;сравниваем со следующим, значит на 1 меньше
    xor    esi,esi        ;начальное значение индекса 0
    lea    ebx,massiv        ;заносим адрес массива
l1:
    mov    ax,[ebx+esi*2]    ;считываем первый элемент
    and    ax,1000000000000000b    ;проверяем старший бит - знак
    mov    sign,ax        ;сохраняем его
    mov    dx,[ebx+esi*2+2]    ;считываем второй элемент
    and    dx,1000000000000000b
    cmp    dx,sign        ;сравниваем знаки
    je    l2        ;если равны идем дальше
    mov    ax,[ebx+esi*2]    ;если нет берем предыдущий элемент
    xchg    [ebx+esi*2+2],ax    ;в меняет со следующим
    mov    [ebx+esi*2],ax    ;заносим в предыдущий
    jmp    l2
l2:
    inc    esi        ;увеличиваем индекс
    loop    l1
;------------------------
;блок вывода исходного массива после обработки
;------------------------
    movzx    ecx,len        ;для вывода нужны все элементы
    shr    ecx,1
    xor    esi,esi
l3:
    mov    ax,[ebx+esi*2]    ;считываем элемент
    push    ax
    xchg    ah,al
    call    print_all        ;вывод старшей цифры
    pop    ax
    call    print_all        ;вывод младшей цифры
    inc    esi        ;увеличиваем индекс
    loop    l3
    mov    dx,offset ctrl        ;адрес строки перевода
    mov    ah,09h        ;перевести строку
    int    21h
;------------------------
;Блок вычисления максимального и среднего арифметического
;максимального и последнего элемента
;------------------------
    movzx    ecx,len
    shr    ecx,1
    dec    cl
    push    ebx        ;адрес массива еще понадобится
    push    ebx
    mov    ax,[ebx]        ;считываем первый элемент
    add    ebx,2        ;переходим к следующему
l6:
    cmp    ax,[ebx]        ;сравниваем со следующим
    jg    l5        ;больше?
    mov    ax,[ebx]        ;нет - заносим в регистр
l5:
    add    ebx,2        ;да - переходим к следующему
    loop    l6
    pop    ebx
    push    eax        ;это наибольший элемент
    movzx    eax,len
    sub    eax,2
    add    ebx,eax        ;перемещаемся на последний элемент
    pop    eax
    add    ax,[ebx]        ;добавляем к наибольшему
    push    ax
    and    ax,1000000000000000b    ;определяем знак
    mov    sign,ax
    pop    ax
    shr    ax,1        ;делим на 2 - среднее арифметическое двух чисел
    or    ax,sign            ;устанавливаем знак
    cmp    sign,1000000000000000b    ;знак минус?
    jne    l4            ;нет - идем дальше
    dec    ax            ;да - увеличиваем среднее
l4:
    pop    ebx
    lea    ebp,massiv1        ;заносим адрес нового массива
    push    ebp
    movzx    ecx,len        ;заносим длину исходного массива
    shr    ecx,1
l8:
    mov    dx,[ebx]        ;считываем элемент исходного массива
    cmp    dx,ax        ;он больше среднего арифметического?
    jle    l7        ;нет - идем дальше
    mov    [ebp],dx        ;да - заносим его в новый массив
    add    ebp,2        ;переводим указатель на следующий элемент нового массива
    inc    len1        ;изменяем длину нового массива
l7:
    add    ebx,2        ;переходим к следующему элементу исходного массива
    loop    l8
    pop    ebp
    movzx    ecx,len1        ;длина нового массива
    test    ecx,ecx        ;она равна нулю?
    jz    l10        ;да - выход
l9:
    mov    ax,[ebp]        ;нет - считываем
    push    ax        ;и выводим
    xchg    ah,al        ;этот уже проходили
    call    print_all
    pop    ax
    call    print_all
    add    ebp,2
    loop    l9
l10:
    ret
;------------------------
;Блок вывода цифр. Выводит в 16-ричной системе.
;Отрицательные выводит согласно 16-ричной системы.
;------------------------
print_all:
    mov    dh,al        ;сохраняем
    and    dh,0Fh        ;младшую цифру
    shr    al,4
    call    print_n        ;вывод старшей цифры
    mov    al,dh        ;восстанавливаем младшую и вывод
print_n:
    cmp    al,10
    sbb    al,69h
    das
    mov    dl,al
    mov    ah,2
    int    21h
    ret

massiv    dw    1,-2,3,4,5,6,7,11,9,10    ;задан произвольно с произвольным количеством
len    db    $-massiv
sign    dw    ?
max    dw    ?
ctrl    db    0Dh,0Ah,'$'
len1    db    0
massiv1:
end    start


Здесь сам файл.

Присоединённый файл ( Кол-во скачиваний: 30 )
Присоединённый файл  PPP.COM 0,32 Kb
PM MAIL   Вверх
seven65
Дата 12.12.2006, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо!!!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

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

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


 




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


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

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