Аватар для nobless1368
14 / 14 / 2
Регистрация: 04.06.2012
Сообщений: 124
Записей в блоге: 1
1

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

18.06.2012, 15:04. Показов 2937. Ответов 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
18.06.2012, 15:04
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
18.06.2012, 15:04
Ответы с готовыми решениями:

Подпрограмма для нахождения максимального элемента массива
пишу простую подпрограмку по нахождению максимального элемента а она почему то не работает(( ind=S; p=0; for (i=1;i&lt;ele;i++)...

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

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

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
 Аватар для nobless1368
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
 Аватар для nobless1368
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
 Аватар для nobless1368
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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.06.2012, 10:44
Помогаю со студенческими работами здесь

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

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

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

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

Нужно написать програму для нахождения максимального элемента массива и его точек вхождени
Нужно написать програму для нахождения максимального элемента массива и его точек вхождения В одном цикле(если массив 9,4,3,9,7,5,9) то маx...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему

Редактор формул (кликните на картинку в правом углу, чтобы закрыть)
Опции темы

Новые блоги и статьи
Отличия между venv, pyenv, pyvenv, virtualenv, pipenv, conda, virtualenvwrapp­­er, poetry и другими в Python
hw_wired 13.02.2025
В Python существует множество средств для управления зависимостями и виртуальными окружениями, что порой вызывает замешательство даже у опытных разработчиков. Каждый инструмент создавался для решения. . .
Навигация с помощью React Router
hw_wired 13.02.2025
React Router - это наиболее распространенное средство для создания навигации в React-приложениях, без которого сложно представить современную веб-разработку. Когда мы разрабатываем сложное. . .
Ошибка "error:0308010C­­:dig­ital envelope routines::unsup­­ported"
hw_wired 13.02.2025
Если вы сталкиваетесь с ошибкой "error:0308010C:digital envelope routines::unsupported" при разработке Node. js приложений, то наверняка уже успели поломать голову над её решением. Эта коварная ошибка. . .
Подключение к контейнеру Docker и работа с его содержимым
hw_wired 13.02.2025
В мире современной разработки контейнеры Docker изменили подход к созданию, развертыванию и масштабированию приложений. Эта технология позволяет упаковать приложение со всеми его зависимостями в. . .
Отличия интерфейсов и типов в TypeScript
hw_wired 13.02.2025
TypeScript - мощное средство для создания качественного и поддерживаемого кода, который расширяет возможности JavaScript, добавляя систему статической типизации. В отличие от динамической типизации. . .
Async/await в циклах JavaScript
hw_wired 13.02.2025
Современная веб-разработка немыслима без асинхронного программирования. Когда приложение выполняет длительные операции - загрузку данных с сервера, чтение файлов или обработку медиа-контента, важно. . .
Git не работает на MacOS после апдейта
hw_wired 13.02.2025
После очередного обновления MacOS многие разработчики сталкиваются с неприятным сюрпризом - Git перестает работать и выдает ошибку "xcrun: error: invalid active developer path". Эта проблема особенно. . .
Git отказывается объединять несвязанные истории
hw_wired 13.02.2025
Git работает безупречно, пока мы не сталкиваемся с особыми ситуациями вроде объединения веток с разными корнями истории. В таких случаях система контроля версий может преподнести неприятный сюрприз в. . .
Проверка email с помощью JavaScript
hw_wired 13.02.2025
Email-адреса имеют довольно запутанную спецификацию, которая допускает множество неочевидных вариантов написания. Например, знали ли вы, что адрес вида "name+tag@domain. com" или даже. . .
Замена всех вхождений строки с помощью JavaScript
hw_wired 13.02.2025
JavaScript предлагает несколько способов для выполнения операций замены в строках, каждый из которых имеет свои особенности и область применения. От простейшей замены первого найденного вхождения до. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru