0 / 0 / 0
Регистрация: 09.05.2018
Сообщений: 16
1
C/C++

Обращение к элементу массива (встроенный Assembler)

09.05.2018, 17:58. Показов 2674. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Изучаю ассемблер. В этой задаче хочу в переменную ср положить какой-то элемент массива(массив и индекс элемента передаю в функцию), но выводит неверно. Например, если index=2, то выводит -9.22596e+61, хотя второй элемент равен 44(если с нуля считать).
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
#include "stdafx.h"
#include "iostream"
using namespace std;
 
double func(double *mas1, double index)
{
    double cp;
    _asm
    {
        lea esi, mas1//кладу в esi адрес первого элемента массива mas1
        mov edx, dword ptr [index]//в edx помещаю индекс элемента, который хочу положить в cp
        mov eax, mas1[edx * 4]//заношу нужный элемент массива в регистр
        mov dword ptr [cp], eax
    }
    cout << cp << endl;
 
    return *mas1;
}
 
int main()
{
    int n;
    cout << "enter n: ";
    cin >> n;
    double mas1[10] = { 22, 100, 44, 15, 2, 36, 53, 23, 82, 5 };
    func(mas1, 2);
    for (int i = 0; i < n; i++)
        cout << mas1[i] << " ";
    return 0;
}
Где ошибка?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.05.2018, 17:58
Ответы с готовыми решениями:

Обращение к элементу массива через ASM(Assembler)
Здравствуйте! Мне нужно написать программу, которая бы просто складывала бы все элементы массива,...

Что быстрее? Обращение к элементу массива или к элементу структуры?
Обращение к элементу массива или к элементу структуры? Экспериментирую с кодом и получается...

Обращение к элементу массива
Доброго вечера! Напомните, пожалуйста, как правильно обращаться к элементу массива ? Часть...

Обращение к элементу массива
Объясните пожалуйста, что происходит в строке помеченной *** void main(){ char str; char...

8
1624 / 809 / 146
Регистрация: 13.06.2015
Сообщений: 3,263
09.05.2018, 21:32 2
Цитата Сообщение от N_p Посмотреть сообщение
dword ptr [index]
А вот тут по-вашему что произойти должно?
Особенно учитывая, что index имеет тип double, что уже само по себе дичайшая ошибка.
То же самое и с cp.
0
0 / 0 / 0
Регистрация: 09.05.2018
Сообщений: 16
09.05.2018, 22:03  [ТС] 3
Цитата Сообщение от Kukuxumushu Посмотреть сообщение
А вот тут по-вашему что произойти должно?
Подразумевалось, что адрес переменной index имеет размер dword.
Но, очевидно, это неверно.
index - это константа, значит имеет фиксированный размер

С типом double сложнее. Нужно какое-то преобразование типов?
0
3405 / 1824 / 489
Регистрация: 28.02.2015
Сообщений: 3,699
09.05.2018, 22:50 4
Цитата Сообщение от N_p Посмотреть сообщение
lea esi, mas1//кладу в esi адрес первого элемента массива mas1
* * * * mov edx, dword ptr [index]//в edx помещаю индекс элемента, который хочу положить в cp
* * * * mov eax, mas1[edx * 4]//заношу нужный элемент массива в регистр
* * * * mov dword ptr [cp], eax
по строкам:
1)зачем, если Вы его нигде больше не используете
2)индекс массива может быть только натуральным числом(первый, второй, . . . милионный). Компилятор С, считает, что массив начинается с нуля, компилятор Pascal, неважно с чег начинается, но автоматически приведит к нулю;
2)Вы читаете в EDX, что-то, что находится по адресу [полтора];
3)После этого в ЕАХ Вы читаете, с адреса, который равен сумме начала адреса массива и значению по адресу [полтора];
3-4)
double 8 байт от:-9 223 372 036 854 775 808 .0 , до:9 223 372 036 854 775 807.0
тип double размером 8-мь, а ЕАХ всего 4-е байта, т.е Вы впихиваете невпихуемое.
1
1624 / 809 / 146
Регистрация: 13.06.2015
Сообщений: 3,263
09.05.2018, 22:52 5
Лучший ответ Сообщение было отмечено N_p как решение

Решение

Цитата Сообщение от N_p Посмотреть сообщение
Нужно какое-то преобразование типов?
Нужно во-1 назначить индексным переменным индексный тип, во-2 у вас какой-то неизвестный науке режим адресации используется, в-3, тип double занимает 8 байт и его за 1 раз не передашь, в-4 зачем функция возвращает всегда первый элемент???
Вот так может чего понятнее станет
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
#include <iostream>
using namespace std;
 
double func(double *mas, int index)
{
double cp;
 
_asm
 {
 push esi
 push edi
 push eax
 
 mov esi,mas
 mov eax,index
 shl eax,3
 add esi,eax
 lea edi,cp
 cld
 movsd
 movsd
 
 pop eax
 pop edi
 pop esi
 }
return cp;
}
 
 
int main()
{
double A[5]={0.5, -3, 1.3, 22, -6.4};
cout<<func(A,2)<<endl;
 
system("pause");
return 0;
}
2
0 / 0 / 0
Регистрация: 09.05.2018
Сообщений: 16
10.05.2018, 08:05  [ТС] 6
Здесь все понятно, кроме того, зачем movsd используется дважды?

А можно ли это сделать без использования стека?
0
1624 / 809 / 146
Регистрация: 13.06.2015
Сообщений: 3,263
10.05.2018, 14:08 7
Цитата Сообщение от N_p Посмотреть сообщение
зачем movsd используется дважды?
2 раза по 4 байта пересылается, нельзя за 1 раз 8 байт переслать
Цитата Сообщение от N_p Посмотреть сообщение
А можно ли это сделать без использования стека?
Это зависит от компилятора. Стек используется для сохранения состояния в целях безопасности. Если вы уберёте push/pop и у вас всё продолжит работать - значит они не нужны.

Добавлено через 46 минут
Индексацию, конечно, можно проще сделать. Сразу не сообразил.
Assembler
1
2
3
mov esi,index
shl esi,3
add esi,mas
1
0 / 0 / 0
Регистрация: 09.05.2018
Сообщений: 16
10.05.2018, 17:10  [ТС] 8
Хорошо, спасибо!

А что, если я хочу в этой же программе, сравнить (cmp) значения в mas[index_1] и mas[index_2]( index_1, index_2 даются на вход) и в зависимости от результата сравнения уже дальше что-то делать. Вопрос: т.к. movsd пересылает dword из esi в edi, тогда мне нужно и mas[index_1] и mas[index_2] заносить в отдельные переменные и сравнивать? Проблема в том, что при сравнении(как я понимаю) нужно работать именно со значениями массива, а значение получаю только используя movsd
0
1624 / 809 / 146
Регистрация: 13.06.2015
Сообщений: 3,263
10.05.2018, 19:50 9
Цитата Сообщение от N_p Посмотреть сообщение
сравнить
Это вам уже надо задействовать FPU. Судя по вашему уровню владению ассемблером, это займёт у вас месяц гденить))
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.05.2018, 19:50
Помогаю со студенческими работами здесь

Обращение к элементу массива
Есть следующий код: TITLE FromDecimalToBinary .686 .model flat option casemap:none ...

Обращение к элементу массива
Есть массив, который приходит мне в формате json, как мне обратиться к примеру ко второму элементу,...

Обращение к элементу массива?
Не пойму в этом коде 15 строчку, а именно x. Что значит esi*2 и что этто за элемент мы получаем?...

Обращение к элементу массива
Как мне обратиться к последнему элементу массива? например: Array // i = 0 тут нужно что бы -1...

Обращение к элементу массива
Здравствуйте! Пытаюсь обратиться к третьему элементу массива, но в результате в регистре ax...

Обращение к любому элементу массива
Я делаю обработчик для динамического количества Series у Chart, обращение к LineSeries без...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru