Содержание
- Ассемблеровская вставка в с++ , не пойму в чем данная ошибка:
- Error c2415 недопустимый тип операнда
- Вопрос
- Ответы
- Все ответы
- Error c2415 недопустимый тип операнда
- Лучший отвечающий
- Вопрос
- Ответы
- Все ответы
- Ошибки компилятора с C2400 по C2499
- Недопустимая ошибка типа операнда
- 1 ответ
Ассемблеровская вставка в с++ , не пойму в чем данная ошибка:
С2415 недопустимый тип операнда.
Вроде бы обнулил (xor edi, edi ), а при сравнении (cmp) всё равно пишет ошибку
Код:
#include
#include
using namespace std;
int main()
<
int mass[10] = < 15, 10, 22, 360, 76, 2, 88, 115, 9, 3 >;
int left, right;
int t;
int count = 10;
left = 0;
right = count — 1;
_asm
<
pushad
mov esi, 1
mov ebx, left
mov eax, right
cycle1 :
cmp ebx, eax
ja exit
cmp esi, 0
jb exit
xor esi, esi
mov ecx, eax
xor edi,edi // edi = 0
cycle2 :
inc edi
usl :
cmp mass[edi * 4], mass[edi * 4 + 4]
jb out_cycle
xchg mass[edi * 4], mass[edi * 4 + 4]
mov edi, 1
out_cycle : loop cycle2
dec eax
xor ecx, ecx
mov ecx, eax
cycle3 :
cmp mass[ecx * 4 — 4], mass[ecx * 4]
jb out_usl1
xchg mass[ecx * 4 — 4], mass[ecx * 4]
mov edi, 1
out_usl1 :
loop cycle3
inc ebx
exit : popad
>
cout Голосование за лучший ответ
Это чель cmp mass[ecx * 4 — 4], mass[ecx * 4]
Вот представь, для процессора то, что в памяти просто нет. Это ему нажно получить: значит он грузить должен из памяти куда-то. но ладно на шину свою, но ты ему снова другую ячейку суешь для сравнения. Значит хочешь или не хочешь, у такого процессора должно быть две шины данных и две адреса. сложно, не знаю такого.
А так обычно указывают регистра и память для сравнения.
Так что загони в начале в регистр, потом с памятью сравнивай.
cmp mass[edi * 4], mass[edi * 4 + 4]
.
xchg mass[edi * 4], mass[edi * 4 + 4]
.
cmp mass[ecx * 4 — 4], mass[ecx * 4]
.
xchg mass[ecx * 4 — 4], mass[ecx * 4]
CISC архитектуры не умеют работать с двумя адресами памяти одновременно напрямую, тебе нужно раскидать по регистрам
Источник
Error c2415 недопустимый тип операнда
Вопрос
Доброго времени суток, пытаюсь инициализировать поля структуры используя ассемблерную вставку в функции, компилятор выдает ошибку (Ошибка 3 error C2415: недопустимый тип операнда) код выглядит так:
Скажите пожалуйста что я делаю неправильно.
Ответы
Видимо потому что константа C++ находится в памяти, а команд память/память в x86 нет.
mov eax, STAGE_1
mov SendData.FStage, eax
Скорее всего про false ассемблер и вовсе ничего не знает.
Забавно так же что код скорее всего хуже чем получится при нормальном присвоении в C++.
This posting is provided «AS IS» with no warranties, and confers no rights.
- Помечено в качестве ответа Maksim Marinov Microsoft contingent staff, Moderator 30 августа 2017 г. 7:58
Я проверял только с неименованным enum:
Для enum’ов с именем не знаю, как это работает.
- Помечено в качестве ответа Maksim Marinov Microsoft contingent staff, Moderator 30 августа 2017 г. 7:58
Все ответы
Видимо потому что константа C++ находится в памяти, а команд память/память в x86 нет.
mov eax, STAGE_1
mov SendData.FStage, eax
Скорее всего про false ассемблер и вовсе ничего не знает.
Забавно так же что код скорее всего хуже чем получится при нормальном присвоении в C++.
This posting is provided «AS IS» with no warranties, and confers no rights.
- Помечено в качестве ответа Maksim Marinov Microsoft contingent staff, Moderator 30 августа 2017 г. 7:58
Ну да, const в С++ на сколько я знаю — не «константа» а, скорее, «переменная только для чтения». Конечно, оптимизирующий компилятор не выделяет память под const-переменную, если ее значение известно на этапе компиляции и мы не берем на нее указатели. Но в ассемблерный код она уходит как переменная, поэтому применить mov таким образом не получится. Вместо const-переменной нужно использовать enum, элемент перечисления всегда воспринимаются как «истинная» константа.
Что касается false (написанного маленькими буквами), то да, он не работает в ассемблере. Но можно использовать FALSE, или просто 0.
Источник
Error c2415 недопустимый тип операнда
Лучший отвечающий
Вопрос
Доброго времени суток, пытаюсь инициализировать поля структуры используя ассемблерную вставку в функции, компилятор выдает ошибку (Ошибка 3 error C2415: недопустимый тип операнда) код выглядит так:
Скажите пожалуйста что я делаю неправильно.
Ответы
Видимо потому что константа C++ находится в памяти, а команд память/память в x86 нет.
mov eax, STAGE_1
mov SendData.FStage, eax
Скорее всего про false ассемблер и вовсе ничего не знает.
Забавно так же что код скорее всего хуже чем получится при нормальном присвоении в C++.
This posting is provided «AS IS» with no warranties, and confers no rights.
- Помечено в качестве ответа Maksim Marinov Microsoft contingent staff, Moderator 30 августа 2017 г. 7:58
Я проверял только с неименованным enum:
Для enum’ов с именем не знаю, как это работает.
- Помечено в качестве ответа Maksim Marinov Microsoft contingent staff, Moderator 30 августа 2017 г. 7:58
Все ответы
Видимо потому что константа C++ находится в памяти, а команд память/память в x86 нет.
mov eax, STAGE_1
mov SendData.FStage, eax
Скорее всего про false ассемблер и вовсе ничего не знает.
Забавно так же что код скорее всего хуже чем получится при нормальном присвоении в C++.
This posting is provided «AS IS» with no warranties, and confers no rights.
- Помечено в качестве ответа Maksim Marinov Microsoft contingent staff, Moderator 30 августа 2017 г. 7:58
Ну да, const в С++ на сколько я знаю — не «константа» а, скорее, «переменная только для чтения». Конечно, оптимизирующий компилятор не выделяет память под const-переменную, если ее значение известно на этапе компиляции и мы не берем на нее указатели. Но в ассемблерный код она уходит как переменная, поэтому применить mov таким образом не получится. Вместо const-переменной нужно использовать enum, элемент перечисления всегда воспринимаются как «истинная» константа.
Что касается false (написанного маленькими буквами), то да, он не работает в ассемблере. Но можно использовать FALSE, или просто 0.
Источник
Ошибки компилятора с C2400 по C2499
В статьях в этом разделе документации объясняется подмножество сообщений об ошибках, создаваемых компилятором.
Компиляторы и средства сборки Visual Studio могут сообщать о различных типах ошибок и предупреждений. После обнаружения ошибки или предупреждения средства сборки могут делать предположения о намерении кода и пытаться продолжить работу, чтобы можно было сообщать о дополнительных проблемах одновременно. Если средства делают неверное предположение, последующие ошибки или предупреждения не могут применяться к проекту. При устранении проблем в проекте всегда начинайте с первой зарегистрированной ошибки (или предупреждения) и выполняйте повторную сборку как можно чаще. Одно исправление может привести к возникновению многих последующих ошибок.
Чтобы получить справку о конкретном диагностическом сообщении в Visual Studio, выберите его в окне вывода и нажмите клавишу F1 . Visual Studio открывает страницу документации для этой ошибки, если она существует. Вы также можете использовать средство поиска в верхней части страницы, чтобы найти статьи о конкретных ошибках или предупреждениях. Кроме того, просмотрите список ошибок и предупреждений по инструменту и введите оглавление на этой странице.
Не все ошибки или предупреждения Visual Studio описаны. Во многих случаях диагностическое сообщение предоставляет все доступные сведения. Если вы приземлились на этой странице при использовании F1 и считаете, что сообщение об ошибке или предупреждении требует дополнительного объяснения, сообщите нам об этом. Кнопки обратной связи на этой странице можно использовать для создания проблемы с документацией на сайте GitHub. Если вы считаете, что ошибка или предупреждение неправы или обнаружена другая проблема с набором инструментов, сообщите о проблеме с продуктом на сайте Сообщество разработчиков. Вы также можете отправить отзыв и ввести ошибки в интегрированной среде разработки. В Visual Studio перейдите в строку меню и выберите «Отправить > отзыв справки>» или отправьте предложение с помощью отправки > отзывов > справки.
Вы можете найти дополнительную помощь по ошибкам и предупреждениям на форумах Microsoft Learn Q&A . Или найдите номер ошибки или предупреждения на сайте Сообщество разработчиков Visual Studio C++. Вы также можете выполнить поиск решений в Stack Overflow .
Ссылки на дополнительные справочные материалы и ресурсы сообщества см. в справке и сообществе Visual C++.
Источник
Недопустимая ошибка типа операнда
NASM выдает следующее сообщение об ошибке:
Где появляется ошибка:
1 ответ
Это может быть потому, что операнд для resb должно быть критическим выражением. Это означает, что это должно быть известно на первом проходе ассемблера (a) .
Вместо этого вы можете убедиться, что используете только значения, уже известные в первом проходе.
Сначала поместите начальную метку в 0x7c00:
Затем измените резервирование пространства, чтобы определить другую метку, и используйте разницу между ними, чтобы вычислить, сколько нужно байтов:
Что это делает, это вычислить количество байтов, уже выведенных ( marker-start оба значения известны до resb утверждение) и вычтите это из числа байтов, которые вы хотели ( 0x7dfe — 0x7c00 = 0x01fe ). Затем он резервирует столько места, как показано в результате вывода списка:
Вы можете видеть, что последние два байта смещены 0x01fe который, учитывая 0x7c00 база, на самом деле 0x7dfe по желанию.
(а) Причина, по которой ваше выражение считается непознаваемым, связана, как мне кажется, с тем фактом, что в нем используется фактический адрес, который необязательно известен на этапе 1. Это подтверждается тем фактом, что 0xffff — start также вызовет ту же ошибку, несмотря на то, что она использует реальный, уже объявленный, ярлык, а не $ ,
Вместо этого используя выражение как 0xffff — (label1 — label2) сами ярлыки могут быть неизвестны, но разница между ними есть.
Источник
- Remove From My Forums
-
Вопрос
-
Доброго времени суток, пытаюсь инициализировать поля структуры используя ассемблерную вставку в функции, компилятор выдает ошибку (Ошибка 3 error C2415: недопустимый тип операнда) код выглядит так:
void CALLBACK TestAsm() { TPipeDataStruct SendData; __asm { MOV SendData.FTerminate, false MOV SendData.FStage, STAGE_1 } }
Скажите пожалуйста что я делаю неправильно.
Ответы
-
Видимо потому что константа C++ находится в памяти, а команд память/память в x86 нет.
Попробуйте так:
mov eax, STAGE_1
mov SendData.FStage, eax
Скорее всего про false ассемблер и вовсе ничего не знает.
Забавно так же что код скорее всего хуже чем получится при нормальном присвоении в C++.
This posting is provided «AS IS» with no warranties, and confers no rights.
-
Помечено в качестве ответа
30 августа 2017 г. 7:58
-
Помечено в качестве ответа
-
Я проверял только с неименованным enum:
typedef enum { STAGE_1 = 1 } ;
Для enum’ов с именем не знаю, как это работает.
-
Помечено в качестве ответа
Maksim MarinovMicrosoft contingent staff, Moderator
30 августа 2017 г. 7:58
-
Помечено в качестве ответа
I have this Visual C++ code:
void kopirovaniPrvku(char pole[]){
_asm{
mov eax, offset pole;
mov bl, [eax + 2];
mov[eax + 7], bl;
mov bl, [eax + 3];
mov[eax + 9], bl;
}
}
int _tmain(int argc, _TCHAR* argv[]){
char polePrvku[10];
polePrvku[0] = 0;
polePrvku[1] = 1;
polePrvku[2] = 2;
polePrvku[3] = 3;
polePrvku[4] = 4;
polePrvku[5] = 5;
polePrvku[6] = 6;
polePrvku[7] = 7;
polePrvku[8] = 8;
polePrvku[9] = 9;
kopirovaniPrvku(polePrvku);
}
I’ve got this function and I want to use OFFSET, but I get this error:
error C2415: improper operand type.
When I use a global array it works without problem.
My question is : Why do I get this error? Is it because paramater pole and polePrvku have a different addresses? I am not interesting in finding a solution, I just want to understand why it doesn’t work.
- Remove From My Forums
-
Question
-
Hello I was wondering if someone could help me out with this error of mine.
double Value = 1.0; ... __asm{ FMUL DWORD PTR DS:[ESI+0x1A8] MOV DWORD PTR DS:[ESI+0x1A8],Value //Error C2415 } ...
-error C2415: improper operand type..
Is the error I’m getting and was wondering how I’d fix this.
Answers
-
Since MOV cannot copy data between memory locations, you have to use a series of MOV instructions with intermediate registers.
Or consider this sequence:
FLD Value
FSTP DWORD PTR DS:[ESI+0x1A8]
-
Marked as answer by
Monday, July 13, 2009 2:39 AM
-
Marked as answer by
-
iirc, ASM has no double type, or even a floating point type of any description.
The next issue you have is that you have no instruction to move 8 bytes into any register…the inline assembler is sort of a 16/32-bit hybrid, but it does not do 64 bit mov instructions at all. (You might be able to fool it into assembling 64-bit instructions if you knew the right data value to embed before the 64-bit instruction, but…I don’t think that works with the inline assembler any more.)
Even if you were to use doubles, you would have to move the eight bytes into the memory location in two moves because you are using a 32-bit compiler on a 32-bit processor. (Even if your machine is 64-bit, and the OS is 64-bit. The assembler is not.)
So, I’d say to use singles, and treat them as 32-bit values, as opposed to floating point values, which the assembler will not understand, or work with in any way that I am aware of.
You can get a lot of the work done using casting. C++ will allow you to cast the float/double to whatever you want. A float can be a DWORD. You might try (*((DWORD*)&Value)), or something like that. I have some examples at home, but basically you cast the float to a DWORD, which is also 32-bits. In assembler, you can use DWORD PTR to tell the assembler what size the operand is.
-
Marked as answer by
Wesley Yao
Monday, July 13, 2009 2:39 AM
-
Marked as answer by
- Remove From My Forums
-
Question
-
Hello I was wondering if someone could help me out with this error of mine.
double Value = 1.0; ... __asm{ FMUL DWORD PTR DS:[ESI+0x1A8] MOV DWORD PTR DS:[ESI+0x1A8],Value //Error C2415 } ...
-error C2415: improper operand type..
Is the error I’m getting and was wondering how I’d fix this.
Answers
-
Since MOV cannot copy data between memory locations, you have to use a series of MOV instructions with intermediate registers.
Or consider this sequence:
FLD Value
FSTP DWORD PTR DS:[ESI+0x1A8]
-
Marked as answer by
Monday, July 13, 2009 2:39 AM
-
Marked as answer by
-
iirc, ASM has no double type, or even a floating point type of any description.
The next issue you have is that you have no instruction to move 8 bytes into any register…the inline assembler is sort of a 16/32-bit hybrid, but it does not do 64 bit mov instructions at all. (You might be able to fool it into assembling 64-bit instructions if you knew the right data value to embed before the 64-bit instruction, but…I don’t think that works with the inline assembler any more.)
Even if you were to use doubles, you would have to move the eight bytes into the memory location in two moves because you are using a 32-bit compiler on a 32-bit processor. (Even if your machine is 64-bit, and the OS is 64-bit. The assembler is not.)
So, I’d say to use singles, and treat them as 32-bit values, as opposed to floating point values, which the assembler will not understand, or work with in any way that I am aware of.
You can get a lot of the work done using casting. C++ will allow you to cast the float/double to whatever you want. A float can be a DWORD. You might try (*((DWORD*)&Value)), or something like that. I have some examples at home, but basically you cast the float to a DWORD, which is also 32-bits. In assembler, you can use DWORD PTR to tell the assembler what size the operand is.
-
Marked as answer by
Wesley Yao
Monday, July 13, 2009 2:39 AM
-
Marked as answer by
Wollen 4 / 4 / 2 Регистрация: 19.08.2013 Сообщений: 26 |
||||
1 |
||||
Ассемблер и С++03.10.2013, 00:30. Показов 6129. Ответов 6 Метки нет (Все метки)
Задание: на с++ вводится строка, нужно реализовать операцию «Игнорирование (исключение) строчных латинских букв, введенных во входной строке при формировании выходной строки.» на ассемблере, затем вывести строку. Вот что пытаюсь сделать:
Добавлено через 36 минут Теперь такой вопрос. Можно ли вызвать функцию для вывода строки 21h (или аналог??) прямо из ассемблрной вставки?
__________________
0 |
Charles Kludge Клюг 7673 / 3188 / 382 Регистрация: 03.05.2011 Сообщений: 8,380 |
||||
03.10.2013, 01:14 |
2 |
|||
Можно ли вызвать функцию для вывода строки 21h (или аналог??) прямо из ассемблрной вставки? Можно.
1 |
Wollen 4 / 4 / 2 Регистрация: 19.08.2013 Сообщений: 26 |
||||
03.10.2013, 11:25 [ТС] |
3 |
|||
Можно. Не компилируется. Что за функцию cputs вы ипользуете? Где она находится? Написал по-другому
Как сделать что-то типа
0 |
Ушел с форума 15703 / 7377 / 980 Регистрация: 11.11.2010 Сообщений: 13,321 |
|
03.10.2013, 11:31 |
4 |
Wollen,
0 |
Клюг 7673 / 3188 / 382 Регистрация: 03.05.2011 Сообщений: 8,380 |
|
03.10.2013, 12:07 |
5 |
Не компилируется. Ну дык замените cputs на _cputs, вам же русским английским языком сказано.
Что за функцию cputs вы ипользуете? Где она находится? Там, где ей и положено быть — в clib. Шаблон в conio.h. cputs Description: The cputs function writes the character string pointed to by buf directly to the console using the putch function. Unlike the puts function, the carriage-return and line-feed characters are not appended to the string. The terminating null character is not written. И да, настройте уж компилятор так, чтобы это соответствовало ANSI C/C++, а не хотелкам билли-боя. Чтобы было понятней — мой код скомпилился под ДОС, вынь и FreeBSD, ваш — только под вынь. Добавлено через 12 минут
system(«pause»); А вот за такой быдлокод в приличном обществе бьют по лицу. Вместо того, чтобы заюзать getch() из msvcrt.dll, который и так в памяти, вы вызываете копию командного процессора, отжирающую от 300кб до 2мб памяти ради <Press any key>.
0 |
0 / 0 / 0 Регистрация: 10.04.2015 Сообщений: 3 |
|
28.10.2015, 22:33 |
6 |
Wollen, , Решение было найдено?
0 |
Ушел с форума 15703 / 7377 / 980 Регистрация: 11.11.2010 Сообщений: 13,321 |
|
29.10.2015, 10:04 |
7 |
AlexbelrBez,
0 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
29.10.2015, 10:04 |
Помогаю со студенческими работами здесь C++ и Ассемблер ассемблер c++ и ассемблер .model small .code _count proc С++ и Ассемблер Искать еще темы с ответами Или воспользуйтесь поиском по форуму: 7 |
I’m trying to call a function from another dll, know her exact address and parameters.
In IDA:
int __userpurge sub_104CC1A0<eax>(int a1<ecx>, double a2<st0>, int a3)
I found a similar answer on stackoverflow.com, but I get the error:
struct typechat
{
unsigned int a;
unsigned int b;
unsigned int type;
};
typechat * point;
DWORD callAddress = 0x4CC1A0 + baseaddr;
__declspec(naked) int SendMsg(char * text, double time, typechat * a3)
{
__asm{
push ebp
mov ebp, esp
push ebx
push a3
mov st0, time // error C2415: invalid operand type
mov ecx, text
call[callAddress]
pop ebx
leave
ret
}
}
error C2415: invalid operand type
switch ( *(_DWORD *)(a3 + 8) )//chat type ,[code from IDA]
{
}
UPDATE:
_
//int __userpurge sub_104CC1A0<eax>(int a1<ecx>, double a2<st0>, int a3)
declspec(naked) int SendMsg(char * text, double nTime, typechat * nType)
{
__asm{
push ebp
mov ebp, esp
push nType
fld nTime
push ecx
mov ecx, text
move eax, [callAddress]
call eax
pop ecx
leave
ret
}
}
This function too does not work! : (Not called callAddress)
I’m trying to call a function from another dll, know her exact address and parameters.
In IDA:
int __userpurge sub_104CC1A0<eax>(int a1<ecx>, double a2<st0>, int a3)
I found a similar answer on stackoverflow.com, but I get the error:
struct typechat
{
unsigned int a;
unsigned int b;
unsigned int type;
};
typechat * point;
DWORD callAddress = 0x4CC1A0 + baseaddr;
__declspec(naked) int SendMsg(char * text, double time, typechat * a3)
{
__asm{
push ebp
mov ebp, esp
push ebx
push a3
mov st0, time // error C2415: invalid operand type
mov ecx, text
call[callAddress]
pop ebx
leave
ret
}
}
error C2415: invalid operand type
switch ( *(_DWORD *)(a3 + 8) )//chat type ,[code from IDA]
{
}
UPDATE:
_
//int __userpurge sub_104CC1A0<eax>(int a1<ecx>, double a2<st0>, int a3)
declspec(naked) int SendMsg(char * text, double nTime, typechat * nType)
{
__asm{
push ebp
mov ebp, esp
push nType
fld nTime
push ecx
mov ecx, text
move eax, [callAddress]
call eax
pop ecx
leave
ret
}
}
This function too does not work! : (Not called callAddress)
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|