Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.71/35: Рейтинг темы: голосов - 35, средняя оценка - 4.71
Пробующий
 Аватар для galileopro
185 / 98 / 10
Регистрация: 28.04.2009
Сообщений: 1,101

Обращение к переменным объекта с использованием указателя this из inline assembler

21.09.2009, 22:15. Показов 7716. Ответов 74
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Мне нужно написать класс на С++ с учетом возможности ввода количества столбцов и строк матрицы. Матрица должна размещаться в динамической памяти. Переменные указателя на матрицу и размеров матрицы должны быть нестатическими членами класса. Обращение к переменным должно осуществляться с использованием указателя this без использования оператора разыменования указателя (->). Вся выделяемая память в программе должна быть освобождена перед выходом.
Я сделал так, но пишет ошибки:
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
#include "stdafx.h"
#include <iostream>
#include "conio.h"
using namespace std;
#include <Windows.H>
 
class Matrix {
private:
int* rows; //пока только строки
 
public:
//Circle () ; недописаный конструктор
void SetRows(int* x) 
{
if ((*x>0)&&(*x<20))  (*this).rows=x;
return;
}
 
int GetRows(void) 
{
return *rows;
}
 
//~Circle () ; недописаный деструктор
};
 
int main()
{
    int* rows=new int;
    
    Matrix t;
 
    t.SetRows(rows);
    cout<<t.GetRows()<<endl;
    return _getch();
}
Помогите исправить.

Добавлено через 38 минут
Вот так получилось. А как массив задать?
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
#include "stdafx.h"
#include <iostream>
#include "conio.h"
using namespace std;
#include <Windows.H>
 
class Matrix {
private:
int* rows;
int* cols;
 
public:
//Matrix(void) недописанный конструктор
 
void SetRows(int* x) 
{
if ((*x>0)&&(*x<20))  (*this).rows=x;
return;
}
 
int GetRows(void) 
{
return *rows;
}
 
void SetCols(int* y) 
{
if ((*y>0)&&(*y<20))  (*this).cols=y;
return;
}
 
int GetCols(void) 
{
return *cols;
}
 
~Matrix(void) //деструктор
{
delete rows;
delete cols;
}
};
 
int main()
{
    int* rows=new int;
    int* cols=new int;
 
    *rows=5;//установим размер матрицы
    *cols=4;
 
    Matrix t;
 
    t.SetRows(rows);
    t.SetCols(cols);
    cout<<t.GetRows()<<" "<<t.GetCols()<<endl;
    return _getch();
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.09.2009, 22:15
Ответы с готовыми решениями:

GCC Inline Assembly перевести в Visual Studio Inline Assembler
Здравствуйте. Есть код на GCC Inline Assembly и его нужно перевести в Visual Studio Inline Assembler. Не работал с GCC Inline Assembly...

inline assembler в СИ
Доброго! каким образом можно связать внешную переменную и встроенный ассмблер в Си? чтоб было примерно так: int abc = 666; ...

Преобразование кода без указателя в код с использованием указателя
Правильно ли выполнил? Исходный код без указателя #include &lt;iostream&gt; #include &lt;cstdlib&gt; #include &lt;fstream&gt; using...

74
Пробующий
 Аватар для galileopro
185 / 98 / 10
Регистрация: 28.04.2009
Сообщений: 1,101
24.09.2009, 03: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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "stdafx.h"
#include <iostream>
#include "conio.h"
#include <ctime>
#include <Windows.H>
using namespace std;
 
class Matrix {
private:
int rows;
int cols;
int vect;
signed int** MyMatrix;   //указатель на начало массива
signed int* MyVector;   //указатель на начало результирующего вектора
 
public:
Matrix(void)
{
 rows =7;
 cols =5;
 vect =cols/2+1;
MyVector = new int[vect];
 
MyMatrix = new int*[cols];
for(int i=0;i<rows;i++) 
MyMatrix[i]= new int[cols];
}
 
void SetRows(int x) 
{
if ((x>0)&&(x<20))rows=x;
return;
}
 
int GetRows(void) 
{
return rows;
}
 
void SetCols(int y) 
{
if ((y>0)&&(y<20)) cols=y;
 vect =cols/2+1;
return;
}
 
int GetCols(void) 
{
return cols;
}
 
void InputCells(int i, int j, signed int rez) 
{
MyMatrix[i][j]=rez;
return;
}
 
void InputRandomMatrix(void)
{
srand(time(NULL));
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++) 
MyMatrix[i][j]=rand()%20;
}
 
void Calculate(void)
{
__asm   
{
mov ebx, this 
xor esi, esi
label1:
xor eax, eax
xor ecx, ecx
 
label2: 
mov edx,[ebx].MyMatrix
mov edx,[edx][ecx]
mov edx,[edx][esi]
add eax, edx ;добавляем элементы нечетного столбца
add ecx, 4 ;переходим к следующей строке
mov edx, [ebx].rows
shl edx, 2
cmp ecx, edx
jl label2
 
mov ecx, [ebx].rows
xor edx, edx
idiv ecx
mov edx, esi
shr edx, 1
mov ecx, [ebx].MyVector
mov [ecx][edx], eax 
 
add esi, 8 ;переходим к следующему нечетному столбцу
mov edx, [ebx].cols
shl edx, 2
cmp esi, edx
jl label1 
}
return;
}
 
int GetVector(int CoordForVector) 
{
return MyVector[CoordForVector];
}
 
int GetVectorSize(void) 
{
return vect;
}
 
~Matrix(void) //деструктор
{
for(int i=0;i<rows;i++) 
delete MyMatrix[i];
delete MyMatrix;
delete MyVector;
}
};
 
int main()
{   
    Matrix t;
    t.InputRandomMatrix();
    t.Calculate();
    for(int i=0; i<t.GetVectorSize(); i++)
    cout<<(int)t.GetVector(i)<<endl;
    return _getch();
}
Ассемблеровская ф-я считает среднее значение каждого нечетного столбца матрицы. Но вот еще не могу реализовать это: "Обращение к параметрам, передаваемым в функцию должно осуществляться с использованием регистров ESP, EBP. Вызов функции осуществить на ассемблере.(ф-и Calculate() имеется в виду)". Это так сказать апогей этой проги. Хуже уже не будет, но как сделать хотя бы это - не знаю.

Не по теме:

XuTPbIu_MuHTAu, не мог бы удалить предыдущее моё сообщение? Оно в этой теме не пригодится все равно.



Добавлено через 40 минут
Вот небольшие поправки.
1) Я зделал, чтобі рандом генерировал как положительніе значения, так и отрицательніе
2) Обнаружено, что ф-я
Assembler
1
idiv <регистр-делитель>
не всегда корректно работает с отрицательными числами, поэтому сделал немного по-другому.
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
void InputRandomMatrix()
{
srand(time(NULL));
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++) 
MyMatrix[i][j]=-rand()%20*2+10;
}
 
void Calculate(void)
{
__asm   
{
...
mov ecx, [ebx].rows
xor edx, edx
neg eax
div ecx
neg eax
mov edx, esi
shr edx, 1
...
}
return;
}
0
Пробующий
 Аватар для galileopro
185 / 98 / 10
Регистрация: 28.04.2009
Сообщений: 1,101
25.09.2009, 17:03  [ТС]
как можно вызвать метод Calculate из inline assembler?
Пробую так, но он вілетае.
C++
1
2
3
4
5
6
7
8
9
10
Matrix t;
typedef void (Matrix::*Calculate)();
Calculate pMethod;
pMethod = &Matrix::Calculate;
    t.InputRandomMatrix();
    __asm
    {  
        CALL pMethod
        ret
    }
0
Эксперт С++
 Аватар для XuTPbIu_MuHTAu
2256 / 771 / 25
Регистрация: 27.05.2008
Сообщений: 1,496
25.09.2009, 17:48
galileopro, эта функция неявно принимает один параметр - указатель на класс. сделай push &t (мб это делается как lea eax,t push eax), затем сделай call pMethod. И зачем там ret ? он не имеет отношения к вызову

Добавлено через 1 минуту
И я был занят вчера,так что упустил нить.У тебя Calculate заработала в конечном итоге?
1
Пробующий
 Аватар для galileopro
185 / 98 / 10
Регистрация: 28.04.2009
Сообщений: 1,101
25.09.2009, 17:58  [ТС]
Да. Щас я віложу код. Но я пока не могу візвать єту Calculate из ассемблерной вставки, а надо именно так.

Добавлено через 1 минуту
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include "stdafx.h"
#include <iostream>
#include "conio.h"
#include <ctime>
#include <windows.h>
using namespace std;
 
 
class Matrix 
{
private:
int rows;
int cols;
int vect;
signed int** MyMatrix;   //указатель на начало массива
signed int* MyVector;   //указатель на начало результирующего вектора
 
public:
Matrix(void)
{
 rows =7;
 cols =5;
 vect =cols/2+1;
MyVector = new int[vect];
 
MyMatrix = new int*[cols];
for(int i=0;i<rows;i++) 
MyMatrix[i]= new int[cols];
}
 
void SetRows(int x) 
{
if ((x>0)&&(x<20))rows=x;
return;
}
 
int GetRows(void) 
{
return rows;
}
 
void SetCols(int y) 
{
if ((y>0)&&(y<20)) cols=y;
 vect =cols/2+1;
return;
}
 
int GetCols(void) 
{
return cols;
}
 
void InputCells(int i, int j, signed int rez) 
{
MyMatrix[i][j]=rez;
return;
}
 
void InputRandomMatrix()
{
srand(time(NULL));
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++) 
MyMatrix[i][j]=-rand()%20+10;
}
 
void Calculate(void)
{
__asm   
{
mov ebx, this 
xor esi, esi
label1:
xor eax, eax
xor ecx, ecx
 
label2: 
mov edx,[ebx].MyMatrix
mov edx,[edx][ecx]
mov edx,[edx][esi]
add eax, edx ;добавляем элементы нечетного столбца
add ecx, 4 ;переходим к следующей строке
mov edx, [ebx].rows
shl edx, 2
cmp ecx, edx
jl label2
 
mov ecx, [ebx].rows
xor edx, edx
cdq
idiv ecx
mov edx, esi
shr edx, 1
mov ecx, [ebx].MyVector
mov [ecx][edx], eax 
 
add esi, 8 ;переходим к следующему нечетному столбцу
mov edx, [ebx].cols
shl edx, 2
cmp esi, edx
jl label1 
}
return;
}
 
int GetVector(int CoordForVector) 
{
return MyVector[CoordForVector];
}
 
int GetVectorSize(void) 
{
return vect;
}
 
int GetMatrix(int i, int j) 
{
return MyMatrix[i][j];
}
 
~Matrix(void) //деструктор
{
for(int i=0;i<rows;i++) 
delete MyMatrix[i];
delete MyMatrix;
delete MyVector;
}
};
 
void IntDivide(void)
{
    int a=0;
    return;
}
int main(void)
{
    Matrix t;
    t.InputRandomMatrix();
    //t.Calculate();
    __asm
    { 
//здесь надо вызвать Calculate
    }
    cout<<"------------Matrix--------------------------"<<endl;
for(int i=0; i<t.GetRows(); i++)
{
  for(int j=0; j<t.GetCols(); j++)
    cout<<(int)t.GetMatrix(i,j)<<"  ";
   cout<<endl;
}
 
cout<<"---------------Vector----------------------"<<endl;
    for(int i=0; i<t.GetVectorSize(); i++)
    cout<<(int)t.GetVector(i)<<endl;
    return _getch();
}
Добавлено через 2 минуты
Вот я заметил, что такой код помещает в регистр eax указатель this.
C++
1
2
3
4
[ASM]__asm
        { 
mov eax, t
        }[/ASM]
А еще есть call - вызов метода класса по его адресу
0
Эксперт С++
 Аватар для XuTPbIu_MuHTAu
2256 / 771 / 25
Регистрация: 27.05.2008
Сообщений: 1,496
25.09.2009, 18:09
указатель this нужно запихнуть на вершину стека перед вызовом
1
Пробующий
 Аватар для galileopro
185 / 98 / 10
Регистрация: 28.04.2009
Сообщений: 1,101
25.09.2009, 18:30  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
Matrix t;
    t.InputRandomMatrix();
    typedef void (Matrix::*Calculate)();
   Calculate pMethod;
   pMethod = &Matrix::Calculate;
    //t.Calculate();
    __asm
    { 
lea eax,t 
push eax 
call pMethod
    }
Почему-то процедура вызывается нормально, однако при этом в this помещается количество столбцов, и потом при вызове
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void Calculate(void)
{
__asm   
{
mov ebx, this 
xor esi, esi
label1:
xor eax, eax
xor ecx, ecx
 
label2: 
mov edx,[ebx].MyMatrix - вылетает, ведь this не тот(
...
Добавлено через 14 минут
Может как-то
C++
1
delegate
поюзать? Или смысла нет?
0
Эксперт С++
 Аватар для XuTPbIu_MuHTAu
2256 / 771 / 25
Регистрация: 27.05.2008
Сообщений: 1,496
25.09.2009, 18:39
MSDN говорит :
You can access data members in C++ without regard to access restrictions. However, you cannot call member functions.
Посидев с дебаггером это,конечно,можно сделать..но все же
1
Пробующий
 Аватар для galileopro
185 / 98 / 10
Регистрация: 28.04.2009
Сообщений: 1,101
25.09.2009, 18:43  [ТС]
Это можно сделать. Иначе лабу бы такую не дали. Процедура вызвалась без глюков. Я её трассировал, она прекрасно вызвалась. Но после этого изменился this на 0000....07 и в mov ebx, this ebx поместилось 7. Может можно как-то єтого избежать?
0
Эксперт С++
 Аватар для XuTPbIu_MuHTAu
2256 / 771 / 25
Регистрация: 27.05.2008
Сообщений: 1,496
25.09.2009, 18:55
galileopro, конечно,можно нужно посмотреть на пролог функции Calculate и понять,что она воспринимает как this.Скорее всего регистр какойнить.

Добавлено через 4 минуты
У меня передается через ecx

Добавлено через 1 минуту
т.е такой код
Assembler
1
2
lea ecx,t 
call pMethod
работает.

Но нужно понимать,что это не поддерживаемое, зависящее от компилятора, решение.Может,этого хватит для сдачи задания,но не могу не предупредить,что чем реже такие фокусы используются,тем лучше.
1
Пробующий
 Аватар для galileopro
185 / 98 / 10
Регистрация: 28.04.2009
Сообщений: 1,101
25.09.2009, 18:58  [ТС]
Я знаю. Я посмотрел этот регистр, но так вызывать нельзя мне поставят "2". Препод сказал так: нужно передать call адрес вызываемой ф-и, помещенной в this, однако перед єтим нужно позаботится, чтобы this - не изменилось. Я пробовал делать puch - pop Но оно восстанавливает не то значение. Вот посмотри как я хочу сделать
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
pMethod = &Matrix::Calculate;
    __asm
    {
push eax 
call pMethod
    }
...
Візівается ф-я
void Calculate(void)
{
__asm   
{
xor ebx, ebx
pop ebx
0
Эксперт С++
 Аватар для XuTPbIu_MuHTAu
2256 / 771 / 25
Регистрация: 27.05.2008
Сообщений: 1,496
25.09.2009, 20:02
что значит "помещенной в this"и "this" не изменилось? Ладно,пофиг
Короче,pop там не поможет. Поскольку после вызова поверх в стек пихается как минимум EBP и адрес возврата. В дебаге еще что-то. Однако можно точно сказать,что если ты перед вызовом запушиш указатель на объект, то в функции он будет в стеке сразу "под" адресом возврата. Это можно посчитать.Но реализация будет отличаться для дебага и релиза,т.к по-разному проходит пролог функции.После вызова нужно не забыть сделать pop.

Добавлено через 15 секунд
что значит "помещенной в this"и "this" не изменилось? Ладно,пофиг
Короче,pop там не поможет. Поскольку после вызова поверх в стек пихается как минимум EBP и адрес возврата. В дебаге еще что-то. Однако можно точно сказать,что если ты перед вызовом запушиш указатель на объект, то в функции он будет в стеке сразу "под" адресом возврата. Это можно посчитать.Но реализация будет отличаться для дебага и релиза,т.к по-разному проходит пролог функции.После вызова нужно не забыть сделать pop.
1
Пробующий
 Аватар для galileopro
185 / 98 / 10
Регистрация: 28.04.2009
Сообщений: 1,101
25.09.2009, 20:07  [ТС]
Вот в методичке сказано такое
Однако,
команда CALL автоматически записывает в стек относительный адрес команды,
следующей непосредственно за командой CALL, и увеличивает после этого
указатель вершины стека. В вызываемой процедуре команда RET использует
этот адрес для возврата в вызывающую процедуру и при этом автоматически
уменьшается указатель вершины стека.
Поєтому я использую ret. Как думаешь, он нужен?
0
Эксперт С++
 Аватар для XuTPbIu_MuHTAu
2256 / 771 / 25
Регистрация: 27.05.2008
Сообщений: 1,496
25.09.2009, 20:09
galileopro, ret вызывается функцией.
1
Пробующий
 Аватар для galileopro
185 / 98 / 10
Регистрация: 28.04.2009
Сообщений: 1,101
25.09.2009, 20:13  [ТС]
Ладно. Спасибо. Я еще почитаю, может чё найду. А вот еще надо такое
Обращение к параметрам, передаваемым в функцию должно осуществляться с использованием регистров ESP, EBP.
Я вот думаю, может передавать в ф-ю this - в качестве параметра?
0
Эксперт С++
 Аватар для XuTPbIu_MuHTAu
2256 / 771 / 25
Регистрация: 27.05.2008
Сообщений: 1,496
25.09.2009, 20:26
galileopro, у тебя параметров вроде нет. Посмотри внимательно на пролог функции и разберись,что там творится с EBP и ESP Попробуй сам,я в свое время справился)

То,что я писал - делать push перед вызовом,и есть передать в качестве параметра.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.09.2009, 20:26

Inline assembler mingw
Добрый вечер ув. пользователи форума. Возникла проблема с ассемблером, и его реализацией в mingw. Имеется функция void call_hook ( void...

Inline Assembler & C++
int main(int argc, char *argv) { perevod(); cout&lt;&lt;&quot;Type Esc to Escape \n&quot;; __asm { mov ah,01h ...

написать программу движущийся графический объект с двумя способоми с использованием статического объекта и с использованием динамического объекта
Движение закрашенного прямоугольника по треугольному контуру с изменением цвета при изменении направления движения.

inline assembler VS чтение по указателю
Доброе время суток. Задача состоит в чтении 1 байта по адресу указателя. Проблема с пониманием, что не так с типами операндов. char...

Как исправить код? / Inline assembler
#include &lt;stdio.h&gt; int main(int argc, char** argv ) { int aa; int bb; aa = 42; bb = 10;


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

Или воспользуйтесь поиском по форуму:
75
Ответ Создать тему
Новые блоги и статьи
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru