Форум программистов, компьютерный форум, киберфорум
Assembler для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
14 / 14 / 2
Регистрация: 04.06.2012
Сообщений: 124
Записей в блоге: 1
1

Ассемблерная вставка в MVS для нахождения максимального элемента массива

18.06.2012, 15:04. Показов 2826. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Написал такую вот штуку:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// 1st_lab.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include <iostream>
#include <conio.h>
 
using namespace std;
const int n=10;
 
int ascending(int a[10]){
    _asm{
        mov ecx,10 //по числу адресов
        lea di, a 
        mov al,0
        cycle:
            mov eax,di
            push eax
            inc esi // перешли на следующий элемент массива
            cmp eax,di
            ja L1
            mov eax,di
L1:     mov [esi], al
        
        mov al, ah
        inc al
        loop cycle
    }
    return 0;
}
 
int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hi! Enter the numbers: ";
    int a[n];
    //заполнение массива
    for(int i=0;i<n;i++){
        cout << endl << i+1 <<". ";
        cin >> a[i];
    }
    cout << "choise what you want:" << endl
        << "1. If you want to display the largest number (default)" << endl
        << "2. If you want to display the smaller number" << endl
        << "3. If you want to display the largest number of negative numbers" << endl
        << "4. If you want to display the smaller number of positive numbers" << endl;
    int choise=1;
    cin >> choise;
    switch(choise){
        case '1': ascending(a);break;
/*      case '2': descending(a,b,c,d,e,f,g,h,i,j);break;
        case '3': negative(a,b,c,d,e,f,g,h,i,j);break;
        case '4': positive(a,b,c,d,e,f,g,h,i,j);break;
*/  }
    cout << "complete";
        getch();
    return 0;
}
Проблема возникает на первой же строчке цикла. Ругается на разный размер операндов, а как исправить понятия не имею. Только начал изучать ассемблер, так что, если кто знает, то расписывайте как можно подробнее заранее спасибо всем откликнувшимся!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.06.2012, 15:04
Ответы с готовыми решениями:

Подпрограмма для нахождения максимального элемента массива
пишу простую подпрограмку по нахождению максимального элемента а она почему то не работает(( ...

Функция для нахождения индекса максимального элемента массива
Помогите написать функцию для нахождения индекса максимального элемента массива. реализуйте функцию...

Рекурсивный метод для нахождения максимального отрицательного элемента массива
class Program { static void Rec(int arr, int n) { int index = -1; if (n &gt; 0)...

Составить программу для нахождения номера максимального элемента массива
4)Известен массив x1,х2,х3,…,х9. Составить программу для нахождения номера максимального элемента....

7
650 / 337 / 37
Регистрация: 04.04.2012
Сообщений: 886
18.06.2012, 15:36 2
Не правильно:
Assembler
1
2
mov eax,di
cmp eax,di
Правильно:
Assembler
1
2
mov eax,edi //или mov ax,di
cmp eax,edi //или cmp ax,di
1
14 / 14 / 2
Регистрация: 04.06.2012
Сообщений: 124
Записей в блоге: 1
18.06.2012, 15:55  [ТС] 3
спасибо, помогло
0
16 / 10 / 0
Регистрация: 14.06.2012
Сообщений: 25
18.06.2012, 16:03 4
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    mov ecx, 9  // выполняем цикл 9 раз
    lea esi, a      // адрес массива в esi
    lodsd       // эквивалентно: mov eax, [esi]; add esi, 4
            // квадратные скобки - операция разыменования
            // к esi прибавляется 4, т.к. считывается двойное слово
    push eax    // сохраняем eax в стеке
    cycle:
        pop eax // в конце процедуры занятый стек должен быть освобожден
        cmp eax, dword ptr [esi]  // сравнения чисел DWORD в регистре eax и по адресу esi
        jg L1       // если eax больше - переход (знаковое сравнение)
        mov eax, [esi]      // записываем большее значение
        L1:
        push eax        // сохраняем новое значение eax в стеке
        add esi, 4      // переходим к следующему элементу
    loop cycle
    pop eax     // освобождаем занятый стек, извлекая максимальный элемент
                // кол-во push-ов должно равняться кол-ву pop-ов
1
14 / 14 / 2
Регистрация: 04.06.2012
Сообщений: 124
Записей в блоге: 1
18.06.2012, 18:02  [ТС] 5
огромное спасибо!
Только есть еще вопрос: я объявил переменную типа DWORD и в нее мувом поместил значение регистра eax, но в ней почему-то какое-то постороннее число. Что я сделал не так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int ascending(int a[n]){
    DWORD l;
    _asm{
        mov ecx, 2                      // выполняем цикл 9 раз
        lea esi, a                      // адрес массива в esi
        lodsd                           // эквивалентно: mov eax, [esi]; add esi, 4
                                        // квадратные скобки - операция разыменования
                                        // к esi прибавляется 4, т.к. считывается двойное слово
        push eax                        // сохраняем eax в стеке
        cycle:
            pop eax                     // в конце процедуры занятый стек должен быть освобожден
            cmp eax, dword ptr [esi]    // сравнения чисел DWORD в регистре eax и по адресу esi
            jg L1                       // если eax больше - переход (знаковое сравнение)
            mov eax, [esi]              // записываем большее значение
        L1:
            push eax                    // сохраняем новое значение eax в стеке
            add esi, 4                  // переходим к следующему элементу
        loop cycle
        pop eax     // освобождаем занятый стек, извлекая максимальный элемент
                 // кол-во push-ов должно равняться кол-ву pop-ов
        mov l,eax
    }
    printf("max=%d\n",l);
    return 0;
}
Добавлено через 54 минуты
все, разобрался
оказывается l нужно было объявить как указатель, т.к. из регистра в него поступает адрес наибольшего элемента массива.
Напишу код, может кому понадобится:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int ascending(int a[n]){
    DWORD *l;
    _asm{
        mov ecx, 1                      // выполняем цикл 9 раз
        lea esi, a                      // адрес массива в esi
        lodsd                           // эквивалентно: mov eax, [esi]; add esi, 4
                                        // квадратные скобки - операция разыменования
                                        // к esi прибавляется 4, т.к. считывается двойное слово
        push eax                        // сохраняем eax в стеке
        cycle:
            pop eax                     // в конце процедуры занятый стек должен быть освобожден
            cmp eax, dword ptr [esi]    // сравнения чисел DWORD в регистре eax и по адресу esi
            jg L1                       // если eax больше - переход (знаковое сравнение)
            mov eax, [esi]              // записываем большее значение
        L1:
            push eax                    // сохраняем новое значение eax в стеке
            add esi, 4                  // переходим к следующему элементу
        loop cycle
        pop eax     // освобождаем занятый стек, извлекая максимальный элемент
                 // кол-во push-ов должно равняться кол-ву pop-ов
        mov l,eax
    }
    printf("max=%d\n",*l);
    return 0;
Добавлено через 19 минут
чуть не забыл добавить, что n, в данном случае, равно 2 и в комментариях опечатка в четвертой строчке: не 9, а 1

Добавлено через 12 минут
После тестирования понял, что функция у меня выводит только первое значение из массива а, что, естественно, не решает поставленной задачи =\ не понимаю где ошибка...
0
16 / 10 / 0
Регистрация: 14.06.2012
Сообщений: 25
18.06.2012, 18:10 6
Если объявлять массив a непосредственно внутри функции, всё должно работать. Если массив передается функции как параметр, тогда передавать нужно его адрес, т.е. int ascending(int *a). Тогда строчка "lea esi, a" изменится на "mov esi, a", т.к. a - уже адрес массива.
0
14 / 14 / 2
Регистрация: 04.06.2012
Сообщений: 124
Записей в блоге: 1
18.06.2012, 19:19  [ТС] 7
в с++, на сколько я знаю, в функцию в любом случае передается указатель на начало массива. Попробовал lea на mov заменить - выдал ошибку "нарушение прав доступа при чтении"
0
16 / 10 / 0
Регистрация: 14.06.2012
Сообщений: 25
19.06.2012, 10:44 8
Предоставленный ассемблерный код работает идеально на чистом ассемблере: проверенно в среде MASM32. Если код ассемблера, вставленный в функцию c++, не выдает ожидаемого результата, ошибка исключительно с синтаксисе c++.
0
19.06.2012, 10:44
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.06.2012, 10:44
Помогаю со студенческими работами здесь

Составить процедуру для нахождения максимального и минимального по модулю элемента одномерного массива A
Здравствуйте. Срочно нужна помощь по данной программе. Составить процедуру для нахождения...

Создание WinApi функции для нахождения максимального элемента массива в нескольких потоках
Задача состоит в следующем: ножно написать программу, которая будет находить максимальное значение...

(Написать программу с классом для нахождения максимального элемента одномерного массива и его индекса.)
Добрый вечер. помогите пожалуйста разобраться почему в консоли не выводит сразу максимальный...

Нужно написать програму для нахождения максимального элемента массива и его точек вхождени
Нужно написать програму для нахождения максимального элемента массива и его точек вхождения В одном...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru