Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.02.2015, 20:25   #1
Ospalex
Новичок
Джуниор
 
Регистрация: 12.02.2015
Сообщений: 2
По умолчанию Работа с массивами в С++ с вставкой на Assembler (сделать вставку)

К программе, которая работает с массивами, нужно прикрутить вставку на ассемблере, суммирующую значение каждого массива (svedArray[i].* - каждого по отдельности). С выводом полученных результатов (третий кейс).

Код:
#include <iostream>
using namespace std;

struct sved {
        int M; int T; int Z;
        float C; float V;        
    };     

int main()
{
    int x;          
    sved svedArray[10];
    
mylabel:
    cout << "\nДействия:\n 1 - ввод данных \n 2 - редактирование \n 3 - результаты \n 4 - выход \n Ваш выбор: ";
    cin >> x;
    
    switch (x) {
        case 1:
         for( int i = 0; i < 10; i++ )
            {
                cout << "\nВы выбрали ввод данных. \nПожалуйста, введите значения M, T и Z: \n";
                cout << "M = "; cin >> svedArray[i].M; cout << "T = "; cin >> svedArray[i].T; cout << "Z = "; cin >> svedArray[i].Z;
                svedArray[i].C = 0.8 * svedArray[i].Z;                
                svedArray[i].V = svedArray[i].M + svedArray[i].T + svedArray[i].Z + svedArray[i].C;
                                                
                cout << "M is " << svedArray[i].M << " ; ";
                cout << "T is " << svedArray[i].T << " ; ";
                cout << "Z is " << svedArray[i].Z << " ; ";
                cout << "C is " << svedArray[i].C << " ; ";
                cout << "V is " << svedArray[i].V << " ; ";
            }            
            goto mylabel;
        case 2:
            int index;
            cout << "Введите номер периода " ; cin >> index;
            cout << "\nВведите M, T, Z для периода " << index << "\n";
            index = index - 1;         
            
            cout << "M = "; cin >> svedArray[index].M; cout << "T = "; cin >> svedArray[index].T; cout << "Z = "; cin >> svedArray[index].Z;
            svedArray[index].C = 0.8 * svedArray[index].Z;                     
            svedArray[index].V = svedArray[index].M + svedArray[index].T + svedArray[index].Z + svedArray[index].C;            
            cout << "V is " << svedArray[index].V << " ; ";
            goto mylabel;
        case 3:
            for( int i = 0; i < 10; i++ )
            {
                cout << "за период # "<<i+1<<" V = " << svedArray[i].V << " \n";
            }
            goto mylabel;
        case 4:
            cout << "Выход.";
            break;
        default:
            cout << "Вы ввели некорректное значение. Выберите опцию 1, 2, 3 или 4 \n";
            goto mylabel;
  }
}
Оно же в онлайн-компиляторе: http://cpp.sh/4cr3
Я в ассемблере ни в зуб ногой. Если кто может написать вставку и объяснить как она работает - буду очень благодарен.
Ospalex вне форума Ответить с цитированием
Старый 13.02.2015, 08:56   #2
challengerr
Участник клуба
 
Аватар для challengerr
 
Регистрация: 30.07.2008
Сообщений: 1,609
По умолчанию

Код:
#include <locale.h>
#include <iostream>
using namespace std;

struct sved {
        int M; int T; int Z;
        float C; float V;        
    };     

int main()
{
    int x;          
    sved svedArray[10];
    
setlocale(LC_ALL, "Russian");

mylabel:
    cout << "\nДействия:\n 1 - ввод данных \n 2 - редактирование \n 3 - результаты \n 4 - выход \n Ваш выбор: ";
    cin >> x;
    
    switch (x) {
        case 1:
         for( int i = 0; i < 10; i++ )
            {
                cout << "\nВы выбрали ввод данных. \nПожалуйста, введите значения M, T и Z: \n";
                cout << "M = "; cin >> svedArray[i].M; cout << "T = "; cin >> svedArray[i].T; cout << "Z = "; cin >> svedArray[i].Z;
                svedArray[i].C = 0.8 * svedArray[i].Z;                
                svedArray[i].V = svedArray[i].M + svedArray[i].T + svedArray[i].Z + svedArray[i].C;
                                                
                cout << "M is " << svedArray[i].M << " ; ";
                cout << "T is " << svedArray[i].T << " ; ";
                cout << "Z is " << svedArray[i].Z << " ; ";
                cout << "C is " << svedArray[i].C << " ; ";
                cout << "V is " << svedArray[i].V << " ; ";
            }            
            goto mylabel;
        case 2:
            int index;
            cout << "Введите номер периода " ; cin >> index;
            cout << "\nВведите M, T, Z для периода " << index << "\n";
            index = index - 1;         
            
            cout << "M = "; cin >> svedArray[index].M; cout << "T = "; cin >> svedArray[index].T; cout << "Z = "; cin >> 

svedArray[index].Z;
            svedArray[index].C = 0.8 * svedArray[index].Z;                     
            svedArray[index].V = svedArray[index].M + svedArray[index].T + svedArray[index].Z + svedArray[index].C;            
            cout << "V is " << svedArray[index].V << " ; ";
            goto mylabel;
        case 3:
{

int result1;
int result2;
int result3;
/*
размер структуры 4 + 4 + 4 + 4 + 4 = 20
struct sved { int M; int T; int Z; float C; float V; };     
*/

result1 = 0;
result2 = 0;
result3 = 0;

__asm
{
mov eax, 9 // количество элементов в массиве
mov ecx, 0 // сумма
lea ebx, svedArray // адрес структуры
mov edx, ebx // копия адреса структуры
add ecx, [edx] // получение значения по адресу структуры
cmp eax, 0 // счетчик количества итераци1
jz ex1 // переход на выход
cycle:
sub eax, 1
add edx, 20
add ecx, [edx]
cmp eax, 0
jnz cycle
ex1:
mov result1, ecx

mov eax, 9 // количество элементов в массиве
mov ecx, 0 // сумма
lea ebx, svedArray // адрес структуры
mov edx, ebx // копия адреса структуры
add edx, 4
add ecx, [edx] // получение значения по адресу структуры
cmp eax, 0 // счетчик количества итераци1
jz ex2 // переход на выход
cycle2:
sub eax, 1
add edx, 20
add ecx, [edx]
cmp eax, 0
jnz cycle2
ex2:
mov result2, ecx

mov eax, 9 // количество элементов в массиве
mov ecx, 0 // сумма
lea ebx, svedArray // адрес структуры
mov edx, ebx // копия адреса структуры
add edx, 8
add ecx, [edx] // получение значения по адресу структуры
cmp eax, 0 // счетчик количества итераци1
jz ex3 // переход на выход
cycle3:
sub eax, 1
add edx, 20
add ecx, [edx]
cmp eax, 0
jnz cycle3
ex3:
mov result3, ecx

}




cout << "result1: " << result1 << "\n";
cout << "result2: " << result2 << "\n";
cout << "result3: " << result3 << "\n";

}

            for( int i = 0; i < 10; i++ )
            {
                cout << "за период # "<<i+1<<" V = " << svedArray[i].V << " \n";
            }
            goto mylabel;
        case 4:
            cout << "Выход.";
            break;
        default:
            cout << "Вы ввели некорректное значение. Выберите опцию 1, 2, 3 или 4 \n";
            goto mylabel;
  }
}
"SPACE.THE FINAL FRONTIER.This's a voyage of starship Enterprise. It's 5-year mission to explore strange new worlds,to seek out new life and civilizations,to boldly go where no man has gone before"
challengerr вне форума Ответить с цитированием
Старый 13.02.2015, 09:09   #3
challengerr
Участник клуба
 
Аватар для challengerr
 
Регистрация: 30.07.2008
Сообщений: 1,609
По умолчанию

Есть 4 основных регистра центрального процессора EAX, EBX, ECX, EDX
Эти регистры являются 32 разрядными, то есть содержат 32 бита.
Если в регистре происходит переполнение, то устанавливается флаг переполнения.

Проверку на переполнение для упрощения я не делал.

На ассемблере циклы создаются инструкциями перехода (jump).
Безусловной инструкцией перехода является инструкция JMP.
Кроме этого есть инструкции перехода по условию.
Одной из инструкций перехода является JZ, которая переходит если получен ноль в регистре EAX.

Помещение числа в регистр производится инструкцией MOV
mov eax, 9 помещает 9 в регистр eax

Для получения адреса переменной используется инструкция LEA

В данном случае задан массив структур, поэтому нужно точно знать размер структуры.

Переменная int имеет размер 4 байта
Переменная float имеет размер 4 байта.
Суммарный размер структуры sved - 20 байт.

Для итерирования по структуре к адресу структуры добавляется 20.
Это осуществляется инструкцией add ecx, [edx]

Если итерирование заканчивается, то переход переход по меткам ex1, ex2, ex3

sub eax, 1 уменьшает на единицу значение в регистре eax

add edx, 20 добавляет 20 к адресу

Значения, которое хранится по адресу добавляется в регистр ecx
add ecx, [edx]

Квадратные скобки означают, что считывается не адрес, а то, что хранится по адресу.


1. Будем считать, что структуры в памяти хранятся последовательно.
2. Будем считать, что данные структуры в памяти хранятся последовательно

Если 1 и 2 не исполняются, то вставка будет неправильной.

Обращение к переменным структуры производится сдвигом по адресу.
Считывание M производится сдвигом на ноль.
Считывание T производится сдвигом на 4 // add edx, 4
Считывание Z производится сдвигом на 8
Считывание C производится сдвигом на 12
Считывание V производится сдвигом на 16

ECX во вставке является регистром накопления суммы.
Поэтому сперва инструкцией mov ecx, 0 сумма устанавливается в ноль

EDX регистр адреса в структуре

EAX счетчик цикла

Вставку можно упростить
"SPACE.THE FINAL FRONTIER.This's a voyage of starship Enterprise. It's 5-year mission to explore strange new worlds,to seek out new life and civilizations,to boldly go where no man has gone before"
challengerr вне форума Ответить с цитированием
Старый 13.02.2015, 14:55   #4
Ospalex
Новичок
Джуниор
 
Регистрация: 12.02.2015
Сообщений: 2
По умолчанию

challengerr, пожалуйста, напишите мне на почту asolex@bk.ru
Попробуем довести программку до ума.
Ospalex вне форума Ответить с цитированием
Старый 13.02.2015, 15:47   #5
challengerr
Участник клуба
 
Аватар для challengerr
 
Регистрация: 30.07.2008
Сообщений: 1,609
По умолчанию

написал по почте
"SPACE.THE FINAL FRONTIER.This's a voyage of starship Enterprise. It's 5-year mission to explore strange new worlds,to seek out new life and civilizations,to boldly go where no man has gone before"
challengerr вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с массивами(assembler) halfeffectsys Помощь студентам 2 19.12.2013 10:55
Работа с массивами (assembler) gvay Помощь студентам 3 13.12.2008 18:20
Работа с массивами (assembler) deni Помощь студентам 2 12.12.2008 10:28
Работа с массивами (assembler) Gespenst Помощь студентам 1 21.04.2008 14:34