Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
#1

Сделать вставку асма - C++

13.06.2010, 21:23. Просмотров 1064. Ответов 19
Метки нет (Все метки)

Помогите пожалуйста!!!!нужно дописать вставку асма, вот задача:

Латинский квадрат. Латинским квадратом порядка n называется квадратная таблица размером nxn, каждая строка и каждый столбец которой содержат все числа от 1 до n. Проверить, является ли заданная целочисленная матрица латинским квадратом.

вот код:

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
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
 
int main()
{
        int **masiv, n, i, j;
        std::cout<<"Enter number= ";
        std::cin>>n;
        masiv=new int*[n];
     for(i=0; i<n; i++)
       masiv[i]=new int[n];
        for(i=0; i<n; i++)
                for(j=0; j<n; j++)
                        masiv[i][j]=(i+j)%n+1;
        for(i=0; i<n; i++)
        {
                for(j=0; j<n; j++)
                        std::cout<<masiv[i][j]<<" ";
                std::cout<<endl;
        }
        getch();
  return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.06.2010, 21:23
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Сделать вставку асма (C++):

пишу программу на С++, и делаю в ней ассемблеровскую вставку. Возможно ли в этой _asm вставке сделать С++ вставку? - C++
Я пишу программу на С++, и делаю в ней ассемблеровскую вставку. Возможно ли в этой _asm вставке сделать С++ вставку? Если да, то как?

Можно ли в С++ сделать вставку на С - C++
Можно ли в С++ сделать вставку на С, как например ассемблерную: _asm{..}

Как сделать ассемблерную вставку? - C++
Нужно сложить два числа. Не могу понять ошибки вроде примеры смотрел вставки делаются именно так #include &lt;iostream&gt; #include &lt;stdio.h&gt;...

Как сделать ассемблерную вставку на с++? - C++
Вроде бы ничего нет сложного, код очень простой, и много где есть, но не идет код У меня c++ BorlandC 3.0, ассемблер MASM использую. Взял...

Сделать из assembler кода ассемблерную вставку в C++ - C++
У меня есть код в ассемблере, мне надо его сделать ассемблерной вставкой, чтоб он работал вот код include \masm32\include\masm32rt.inc...

Передача значения в asm вставку - C++
Есть код: int d = 7; _asm { PUSH 1 PUSH d } Как передать значение переменной d в asm вставку, именно цифру...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
vital792
1990 / 1262 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
13.06.2010, 21:29 #2
Где то я это уже сегодня видел) а не указано какой набор инструкций можно использовать? (fpu mmx sse)?

Добавлено через 2 минуты
и опять что вставлять то? опять все переписать на ассемблер?
BoDRbIi
60 / 10 / 3
Регистрация: 21.07.2009
Сообщений: 250
13.06.2010, 22:27 #3
Я так понял надо сделать вставку. точнее фун-цию на ассемблере которая бы проводила вычисления?
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
13.06.2010, 23:35  [ТС] #4
Совершенно верно, нужно сделать вставку, которая бы делала вычисления
vital792
1990 / 1262 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
14.06.2010, 08:39 #5
я не вижу ничего лучше чем
1. Создать эталонный вектор [1..n] - для сравнения
2. В цикле сортировать строки матрицы и сравнивать с эталонным вектором
3. Транспонировать и повторить шаг2.
Это решение в лоб - очень громоздкое и медленное. Может кто подскажет способ оптимальнее?
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
14.06.2010, 10:40  [ТС] #6
Блин, по ходу, сеня я её не здамблин, зачетная прога.

Добавлено через 1 час 7 минут
Вопрос жизни и смертипросто необходима помощь
vital792
1990 / 1262 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
14.06.2010, 10:55 #7
Вот половина решения:
Assembler
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
58
59
bool IsLatin(int **matrix, int n)
{
    bool result;
    int *vector = new int[n];
    for(int i=0; i<n; i++)
        vector[i] = i+1;
    int *temp = new int[n];
    _asm
     {
         mov    ecx, n
         xor    ebx, ebx
_loop0:
         push   ecx
         push   ebx
         mov    eax, [matrix]
         mov    esi, [eax+ebx]
         mov    ecx, n
         mov    edi, [temp]
         rep    movsd
_loop1:
         mov    ecx, n
         mov    esi, [temp]
         xor    ebx, ebx
_loop2:
         lodsd
         cmp    eax, dword ptr [esi]
         jbe    no_swap
         xchg   eax, dword ptr [esi]
         mov    dword ptr [esi-4], eax
         inc    ebx
no_swap:
         loop   _loop2
         cmp    ebx, 0
         jne    _loop1
 
         mov    edi, [vector]
         mov    ecx, n
         repnz  cmpsd
         jz _noLatin
         pop    ebx
         add    ebx, 4
         pop    ecx
         loop   _loop0
         jmp    _Latin
_noLatin:
         pop    eax
         pop    eax
         xor    eax, eax
         mov    result, al
         jmp    _end
_Latin:
         mov    eax, 1
         mov    result, al
_end:
     }
    delete [] vector;
    delete [] temp;
    return result;
}
Осталось транспонировать матрицу и вызвать функцию IsLatin еще раз.
Вызов:
C++
1
2
if(IsLatin(masiv, n))
       cout<<"Matrix is Latin Square";
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
14.06.2010, 10:59  [ТС] #8
а как нить, еще подробней можно???если не сложно конечно
vital792
1990 / 1262 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
14.06.2010, 11:14 #9
Assembler
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
    _asm
     {
         mov    ecx, n // кол-во элементов
         xor    ebx, ebx //индекс
_loop0:
         push   ecx     // сохраняем счетчик
         push   ebx     // и индекс
         mov    eax, [matrix]   // получим указатель на матрицу
         mov    esi, [eax+ebx]  // разыменуем с масштабированием(т.е. получим в цикле указатели на строки матрицы)
         mov    ecx, n          // 
         mov    edi, [temp]     // указатель на временный вектор(в нем будем хранить сортированные строки матрицы)
         rep    movsd           // копируем строку
_loop1:                         // далее - обычная сортировка массива пузырьком
         mov    ecx, n
         mov    esi, [temp]
         xor    ebx, ebx
_loop2:
         lodsd
         cmp    eax, dword ptr [esi]
         jbe    no_swap
         xchg   eax, dword ptr [esi]
         mov    dword ptr [esi-4], eax
         inc    ebx
no_swap:
         loop   _loop2
         cmp    ebx, 0
         jne    _loop1
                                // до сюда
         mov    edi, [vector]   // а тут сравниваем сортированную строку с эталонным вектором
         mov    ecx, n
         repnz  cmpsd
         jz _noLatin            // не похожа
         pop    ebx             // восстанавливаем регистры
         add    ebx, 4          // индекс массива (+sizeof(int))
         pop    ecx
         loop   _loop0          // цикл по строкам матрицы
         jmp    _Latin          // прошли все строки удачно
_noLatin:
         pop    eax             // не удачно
         pop    eax             //  - выровняем стек
         xor    eax, eax        // result = false;
         mov    result, al
         jmp    _end
_Latin:
         mov    eax, 1          // result = true;
         mov    result, al
_end:
     }
Эта функция проверяет только строки. Чтобы проверить столбцы транспонируй матрицу( в двойном цикле замени i-й на j-й) и вызови функцию для транспонированной матрицы
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
14.06.2010, 11:22  [ТС] #10
Я наверное не правильно понял, но вот что у мя получилось, исправьте если не правильно:
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
 
int main()
{       
        setlocale(LC_ALL, "Russian");
        int **masiv, n, i, j;
        std::cout<<"Введите кол-во элементов= ";
        std::cin>>n;
        masiv=new int*[n];
     for(i=0; i<n; i++)
       masiv[i]=new int[n];
        for(i=0; i<n; i++)
                for(j=0; j<n; j++)
                        masiv[i][j]=(i+j)%n+1;
        for(i=0; i<n; i++)
        {
                for(j=0; j<n; j++)
                        std::cout<<masiv[i][j]<<" ";
                std::cout<<endl;
        }
        if(IsLatin(masiv, n))
       cout<<"Matrix is Latin Square";
        bool IsLatin(int **matrix, int n)
{
        bool result;
        int *vector = new int[n];
        for(int i=0; i<n; i++)
                vector[i] = i+1;
        int *temp = new int[n];
        _asm
         {
                 mov    ecx, n // кол-во элементов
                 xor    ebx, ebx //индекс
_loop0:
                 push   ecx             // сохраняем счетчик
                 push   ebx             // и индекс
                 mov    eax, [matrix]   // получим указатель на матрицу
                 mov    esi, [eax+ebx]  // разыменуем с масштабированием(т.е. получим в цикле указатели на строки матрицы)
                 mov    ecx, n                  // 
                 mov    edi, [temp]             // указатель на временный вектор(в нем будем хранить сортированные строки матрицы)
                 rep    movsd                   // копируем строку
_loop1:                                                 // далее - обычная сортировка массива пузырьком
                 mov    ecx, n
                 mov    esi, [temp]
                 xor    ebx, ebx
_loop2:
                 lodsd
                 cmp    eax, dword ptr [esi]
                 jbe    no_swap
                 xchg   eax, dword ptr [esi]
                 mov    dword ptr [esi-4], eax
                 inc    ebx
no_swap:
                 loop   _loop2
                 cmp    ebx, 0
                 jne    _loop1
                                                                // до сюда
                 mov    edi, [vector]   // а тут сравниваем сортированную строку с эталонным вектором
                 mov    ecx, n
                 repnz  cmpsd
                 jz     _noLatin                        // не похожа
                 pop    ebx                             // восстанавливаем регистры
                 add    ebx, 4                  // индекс массива (+sizeof(int))
                 pop    ecx
                 loop   _loop0                  // цикл по строкам матрицы
                 jmp    _Latin                  // прошли все строки удачно
_noLatin:
                 pop    eax                             // не удачно
                 pop    eax                             //  - выровняем стек
                 xor    eax, eax                // result = false;
                 mov    result, al
                 jmp    _end
_Latin:
                 mov    eax, 1                  // result = true;
                 mov    result, al
_end:
         } 
        }
        delete [] vector;
        delete [] temp;
        getch();
        return result;
        
  
}
vital792
1990 / 1262 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
14.06.2010, 11:35 #11
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
bool IsLatin(int **matrix, int n);
 
int main(int argc, char* argv[])
{
     int **masiv, n, i, j;
     std::cout<<"Enter number= ";
     std::cin>>n;
     masiv=new int*[n];
     for(i=0; i<n; i++)
         masiv[i]=new int[n];
     for(i=0; i<n; i++)
         for(j=0; j<n; j++)
             masiv[i][j]=(i+j)%n+1;
     for(i=0; i<n; i++)
     {
         for(j=0; j<n; j++)
             std::cout<<masiv[i][j]<<" ";
         std::cout<<endl;
     }
     getch();
 
     if(IsLatin(masiv, n))
                { // транспонирование и повторная проверка
         std::cout<<"Matrix is Latin Square";
}
 
     return 0;
}
 
bool IsLatin(int **matrix, int n)
{
    bool result;
    int *vector = new int[n];
    for(int i=0; i<n; i++)
        vector[i] = i+1;
    int *temp = new int[n];
    _asm
     {
         mov    ecx, n // кол-во элементов
         xor    ebx, ebx //индекс
_loop0:
         push   ecx     // сохраняем счетчик
         push   ebx     // и индекс
         mov    eax, [matrix]   // получим указатель на матрицу
         mov    esi, [eax+ebx]  // разыменуем с масштабированием(т.е. получим в цикле указатели на строки матрицы)
         mov    ecx, n          // 
         mov    edi, [temp]     // указатель на временный вектор(в нем будем хранить сортированные строки матрицы)
         rep    movsd           // копируем строку
_loop1:                         // далее - обычная сортировка массива пузырьком
         mov    ecx, n
         mov    esi, [temp]
         xor    ebx, ebx
_loop2:
         lodsd
         cmp    eax, dword ptr [esi]
         jbe    no_swap
         xchg   eax, dword ptr [esi]
         mov    dword ptr [esi-4], eax
         inc    ebx
no_swap:
         loop   _loop2
         cmp    ebx, 0
         jne    _loop1
                                // до сюда
         mov    edi, [vector]   // а тут сравниваем сортированную строку с эталонным вектором
         mov    ecx, n
         repnz  cmpsd
         jz _noLatin            // не похожа
         pop    ebx             // восстанавливаем регистры
         add    ebx, 4          // индекс массива (+sizeof(int))
         pop    ecx
         loop   _loop0          // цикл по строкам матрицы
         jmp    _Latin          // прошли все строки удачно
_noLatin:
         pop    eax             // не удачно
         pop    eax             //  - выровняем стек
         xor    eax, eax        // result = false;
         mov    result, al
         jmp    _end
_Latin:
         mov    eax, 1          // result = true;
         mov    result, al
_end:
     }
    delete [] vector;       // освободим память
    delete [] temp;
    return result;
}
Добавлено через 8 минут
Цитата Сообщение от Vasal Посмотреть сообщение
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
std::cout<<masiv[i][j]<<" ";
std::cout<<endl;
}
в этом цикле ты получаешь свой латинский квадрат так что результатбудет всегда положительный.
Добавь еще цикл для ввода произвольной матрицы чтобы проверить результат

Добавлено через 1 минуту
Цитата Сообщение от Vasal Посмотреть сообщение
for(i=0; i<n; i++)
for(j=0; j<n; j++)
masiv[i][j]=(i+j)%n+1;
не то скопировал)) - в этом цикле
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
14.06.2010, 11:35  [ТС] #12
он у мя чето не отпечатывает того что нужно,нада чтоб он отпечатал 2 ответа, т.е 2 латинских квадрата, один чтоб был языка си, а другой вставки асма,я чет щас пытался этого добится, но почему то не получилось
vital792
1990 / 1262 / 57
Регистрация: 05.06.2010
Сообщений: 2,213
14.06.2010, 11:39 #13
так я не понял надо всего лишь получить этот квадрат? А как же
Цитата Сообщение от Vasal Посмотреть сообщение
Проверить, является ли заданная целочисленная матрица латинским квадратом.
? Данная функция как раз проверяет является ли введенная матрица этим квадратом. Я че зря старался? этого не надо? как раз получить его никаких проблем - проверить куда сложнее
Vasal
0 / 0 / 0
Регистрация: 16.03.2010
Сообщений: 55
14.06.2010, 11:45  [ТС] #14
нет, это нада, я имелл в виду, то что, их нужно отпечатать, сначала в С а потом сразу после него должен следовать асм.ну и потом типа конец программы, все в одной, я вот хотел этого добится но чет не получилось
Orwomoi
63 / 62 / 2
Регистрация: 16.11.2009
Сообщений: 156
14.06.2010, 12:36 #15
хмм... Если латинский квадрат содержит последовательность чисел 1..n Этим можно воспользоваться при сортировке.
1. Выделяем память под строку длины n
2. заполняем нулями.
3. Хватаем первый элемент из квадрата,
4. проверяем нe больше ли он числа n,
5. и ставим его во временную строку на место равное его порядковому числу.
5.5 еще можно проверить на 0 место, куда ставим элемент из квадрата. Если там не 0, значит туда уже копировали элемент из этой строки квадрата, а значит в строке 2 одинаковых числа, чего не может быть в латинском квадрате.
6. По завершении работы со строкой из квадрата сканируем временную строку (scas) на 0. Если в строке остался ноль, значит в строке квадрата отсутвсует один из элементов последовательности 1..n
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.06.2010, 12:36
Привет! Вот еще темы с ответами:

Trie дерево, реализовать вставку - C++
вообщем в алгоритмах я не силён... накидал код, знаю что он уродлив и не работает (я несколько раз переписывал add() поэтому там есть...

Не могу запустить ассемблерную вставку на c++ - C++
Вставка находит скалярное произведение двух векторов, помогите запустить __asm { movaps xmm0, xmmword ptr // 0 | A.z |...

Нужно переделать С++ функцию на ассемблерную вставку - C++
Вот у меня имеется функция,осуществляющая реверс строки на С++ void reverse(const char *s) { if (s &amp;&amp; *s) { int l; for (l =...

Помогите написать очень маленькую ассемблерную вставку - C++
я слышал что по новым стандартам вот такая конструкция не работает int n; cin &gt;&gt; n; int m пишет размер статистического масива...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
14.06.2010, 12:36
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru