Error c2415 недопустимый тип операнда

Ассемблеровская вставка в с++ , не пойму в чем данная ошибка: С2415 недопустимый тип операнда.Вроде бы обнулил (xor edi, edi ), а при сравнении (cmp) всё равно пишет ошибкуКод:#include #include using namespace std; int main() ;int left, right;int t;int count = 10;left = 0;right = count — 1;_asmcout Голосование за лучший ответ Это чель […]

Содержание

  1. Ассемблеровская вставка в с++ , не пойму в чем данная ошибка:
  2. Error c2415 недопустимый тип операнда
  3. Вопрос
  4. Ответы
  5. Все ответы
  6. Error c2415 недопустимый тип операнда
  7. Лучший отвечающий
  8. Вопрос
  9. Ответы
  10. Все ответы
  11. Ошибки компилятора с C2400 по C2499
  12. Недопустимая ошибка типа операнда
  13. 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

  • 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

  • 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

  • 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

Wollen

4 / 4 / 2

Регистрация: 19.08.2013

Сообщений: 26

1

Ассемблер и С++

03.10.2013, 00:30. Показов 6129. Ответов 6

Метки нет (Все метки)


Задание: на с++ вводится строка, нужно реализовать операцию «Игнорирование (исключение) строчных латинских букв, введенных во входной строке при формировании выходной строки.» на ассемблере, затем вывести строку.

Вот что пытаюсь сделать:

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
#include "stdafx.h"
#include <iostream>
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
    char buff[20]="HELLO ASseMbler!!";
    char message[20]="";
    __asm{
    lea si,buff
    lea di,message
    mov bx,0
    //mov al, [si+bx] //error C2432: недопустимая ссылка на 16-разрядные данные в "второй операнд" 
    cmp al,'A'
    // ...
    cmp al,'Z'
    //...
    //mov [di+bx], al //error C2432: недопустимая ссылка на 16-разрядные данные в "первый операнд"
                      //error C2415: недопустимый тип операнда
    };
    cout<<message<<"n"; //должно быть на выводе: "HELLO ASM!!"
    system("pause");
    return 0;
}

Добавлено через 36 минут
Разобрался. Надо заменить si на esi, di на edi.

Теперь такой вопрос. Можно ли вызвать функцию для вывода строки 21h (или аналог??) прямо из ассемблрной вставки?
Выдаёт ошибку «Необработанное исключение по адресу 0x00B37B21 в Lab4asm.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xFFFFFFFF»

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Charles Kludge

Клюг

7673 / 3188 / 382

Регистрация: 03.05.2011

Сообщений: 8,380

03.10.2013, 01:14

2

Цитата
Сообщение от Wollen
Посмотреть сообщение

Можно ли вызвать функцию для вывода строки 21h (или аналог??) прямо из ассемблрной вставки?

Можно.

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
//#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
 
main(int argc, char* argv[])
{
    char buff[20]="HELLO ASseMbler!!";
//    char message[20]="";
_asm{
    lea esi, buff
    push    esi     // сохраняем адрес буфера для вывода cputs()
    mov edi, esi
l:  lodsb
    or  al,al
    jz  done
    cmp     al,'a'
    jb  s
    cmp al,'z'
    jbе    l
s:  stosb
    jmp l
done:  stosb
    call    cputs
    add esp,4
    };
    cout<<endl<<buff<<endl; //должно быть на выводе: "HELLO ASM!!"
    getch();
//    system("pause");
    return 0;
}



1



Wollen

4 / 4 / 2

Регистрация: 19.08.2013

Сообщений: 26

03.10.2013, 11:25

 [ТС]

3

Цитата
Сообщение от Charles Kludge
Посмотреть сообщение

Можно.

Не компилируется. Что за функцию cputs вы ипользуете? Где она находится?
Ошибки
error C2400: синтаксическая ошибка во встроенном коде на языке ассемблера в «код операции»; обнаружено «l»
error C4996: ‘cputs’: The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _cputs. See online help for details.

Написал по-другому

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
#include "stdafx.h"
#include <iostream>
using namespace std;
#define Nmax 30
int _tmain(int argc, _TCHAR* argv[])
{
    char buff[Nmax], message[Nmax]="";
    cout<<"***** Vvedite stroku dlya preobrazovaniya *****n";
    cin.getline(buff,Nmax);
    __asm{
    lea esi,buff
    lea edi,message
    mov ebx,0
    mov ecx,0
copymes:
    mov al, [esi+ebx] 
    cmp al,''
    je endcp
    cmp al,'a'
    jl write  //al<a
    cmp al,'z' 
    jg write  //al>z
    inc ebx
    jmp copymes
write:
    mov [edi+ecx], al
    inc ebx
    inc ecx
    jmp copymes
endcp:  
    };
    cout<<message<<"n";
    system("pause");
    return 0;
}

Как сделать что-то типа
mov edx, edi
mov ah, 9
int 21h
Компилируется, но когда доходит до вывода, выдаёт: «Необработанное исключение по адресу 0x00374FB7 в Lab4asm.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xFFFFFFFF»



0



Ушел с форума

Автор FAQ

15703 / 7377 / 980

Регистрация: 11.11.2010

Сообщений: 13,321

03.10.2013, 11:31

4

Wollen,
не будет 21h прерывание работать под Windows, для него нужен DOS — сформируй строку и используй для ее вывода Сишное cout<<



0



Клюг

7673 / 3188 / 382

Регистрация: 03.05.2011

Сообщений: 8,380

03.10.2013, 12:07

5

Цитата
Сообщение от Wollen
Посмотреть сообщение

Не компилируется.

Ну дык замените cputs на _cputs, вам же русским английским языком сказано.
#define cputs _cputs
Что за компайлер? Вышивальная студия от некрософта?
У меня кросплатформенный Watcom C/C++.

Цитата
Сообщение от Wollen
Посмотреть сообщение

Что за функцию cputs вы ипользуете? Где она находится?

Там, где ей и положено быть — в clib. Шаблон в conio.h.

cputs
Synopsis:
#include <conio.h>
int cputs( const char *buf );

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 минут

Цитата
Сообщение от Wollen
Посмотреть сообщение

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



Ушел с форума

Автор FAQ

15703 / 7377 / 980

Регистрация: 11.11.2010

Сообщений: 13,321

29.10.2015, 10:04

7

AlexbelrBez,
не стоит заниматься некрофилией и ждать ответ на вопрос заданный 03.10.2013



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

29.10.2015, 10:04

Помогаю со студенческими работами здесь

C++ и Ассемблер
По мере решения одной задачи в С++ я уперся в систему команд ассемблера. И возник вопрос, если я…

ассемблер
нужно написать програму на ассемблере чтобы…

c++ и ассемблер
есть процедура на ассемблер

.model small

.code

_count proc
push bp
xor ebp, ebp
mov…

С++ и Ассемблер
Привет всем. У меня вопрос по IAR for MSP430. Мне необходимо в проекте на С++ использовать функцию,…

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

Или воспользуйтесь поиском по форуму:

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)

 
  • Home
  • Forum
  • Games
  • Shop

    • Gold & Powerleveling
    • Game Keys
    • Game Deals
    • Dedicated Servers
    • Merchandise
    • Gaming Desktops
  • The Black Market
Register FAQ Today’s Posts Search
Go Back  
elitepvpers

> Coders Den
> General Coding
inline ASM, error C2415: improper operand type
inline ASM, error C2415: improper operand type

You last visited: Today at 13:12

  • Please register to post and access all features, it’s quick, easy and FREE!

Advertisement

Advertise with us!

Discussion on inline ASM, error C2415: improper operand type within the General Coding forum part of the Coders Den category.

Reply

Old
11/17/2011, 13:45

 
#1

 

elite*gold: 0

The Black Market: 0/0/0

Join Date: Nov 2011

Posts: 6

Received Thanks: 0

inline ASM, error C2415: improper operand type

This is how the native function looks like:

Code:

006952E9 - 8B 44 24 04                - mov eax,[esp+04]
006952ED - 89 41 20                   - mov [ecx+20],eax
006952F0 - C2 0400                    - ret 0004

Now this is how my hook for this function looks like:

Code:

void Naked NewCooldown()
{
	__asm
	{
		MOV dwCooldown, [ESP+0x04]
		MOV [ECX+0x20], dwCooldown
		RET 4
	}
}

I would like to store value of [ESP+0x04] in DWORD variable ‘dwCooldown’ but i am getting an error:

Code:

error C2415: improper operand type

can I count on your help?

cAddict is offline

 

Old
11/17/2011, 14:20

 
#2

link

 

link's Avatar

 

elite*gold: 1

The Black Market: 0/0/0

Join Date: Jul 2005

Posts: 553

Received Thanks: 451

Trying to access two memory addresses in one instruction is invalid.
Also, in 32-bit ret is just an alias for retn.

Code:

void Naked NewCooldown()
{
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [dwCooldown],EAX
		MOV [ECX+0x20],EAX
		RETN 4
	}
}
link is offline

 

Thanks

1 User

Old
11/17/2011, 14:50

 
#3

cAddict

 

elite*gold: 0

The Black Market: 0/0/0

Join Date: Nov 2011

Posts: 6

Received Thanks: 0

thanks link, but now i’ve got another problem, omg.

Code:

char chCooldownInfo[0] = "Cooldown value: %dn";
void Naked NewCooldown()
{
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [dwCooldown], EAX
		MOV [ECX+0x20], EAX

		// trying to push EAX on stack as a variable for chCooldownInfo
		// EAX already hold the value so there is no need to copy dwCooldown on stack, right?
		PUSH EAX
		MOV EAX, OFFSET chCooldownInfo
		PUSH EAX
		CALL printf

		// clean up the stack
		POP EBX
		POP EBX

		// return
		RETN 4
	}
}

Code:

void CooldownHandler()
{
	char chCooldownInfo[] = "cooldown value: %dn";

	__asm
	{
		MOV EAX, [dwCooldown]
		PUSH EAX
		MOV EAX, OFFSET chCooldownInfo
		PUSH EAX

		CALL printf

		POP EBX
		POP EBX
	}
}

void Naked NewCooldown()
{
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [dwCooldown], EAX
		MOV [ECX+0x20], EAX
		CALL CooldownHandler
		RETN 4
	}
}

I’ve tried both ways, both fail.

What I want to do is to print to console value of dwCooldown everytime my Cooldown hook is being executed but this code crash my game client.

edit:
i am getting really confused about asm. now im getting another error on:

Code:

		MOV EAX, OFFSET chCooldownInfo
error C2415: improper operand type

while this is working perfectly fine:

Code:

#include "stdafx.h"
#include "stdio.h"
#include "process.h"

char chFormat[] = "%s %dn";
char chValue[] = "value:";
int	 iValue = 652;


int main( void )
{
   __asm
   {
      mov  eax, [iValue]
      push eax
      mov  eax, offset chValue
      push eax
      mov  eax, offset chFormat
      push eax

      call dword ptr [printf]

      pop  ebx
      pop  ebx
      pop  ebx
   }

   system("pause");
}

what is going on? oO

cAddict is offline

 

Old
11/17/2011, 18:05

 
#4

link

 

link's Avatar

 

elite*gold: 1

The Black Market: 0/0/0

Join Date: Jul 2005

Posts: 553

Received Thanks: 451

Cleaning the stack by overwriting a ‘sensitive’ register like ebx (it could still hold some value important to the caller) isn’t the best way.
In case of calling a cdecl-function just increment esp by the amount of bytes you have pushed before and are meant as parameters (printf gets 2 dwords as params -> add esp,8).

Either define chCooldownInfo as a global variable and use «offset chCooldownInfo» or define it inside a function to make it exist on the stack as long as the function itself gets executed and use «lea eax,[chCooldownInfo]».
In the latter case chCooldownInfo is just a pseudo-label for sth like ebp-4, therefore its address has to be calculated, in the former chCooldownInfo is an absolute label, means «push offset chCooldownInfo» would be like «push 00400210h»

Try this:

Code:

void Naked NewCooldown()
{
	char chCooldownInfo[] = "Cooldown value: %dn";
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [dwCooldown], EAX
		MOV [ECX+0x20], EAX

		PUSH EAX
		LEA EAX,[chCooldownInfo]
		PUSH EAX
		CALL printf

		ADD ESP,4*2

		RETN 4
	}
}

EDIT:
ah, and as far as I recall you have to call API functions in this manner «call dword ptr [printf]» as no jump-table gets generated and printf is the address of an IAT-entry which holds the function’s actual address.

link is offline

 

Thanks

1 User

Old
11/17/2011, 19:41

 
#5

cAddict

 

elite*gold: 0

The Black Market: 0/0/0

Join Date: Nov 2011

Posts: 6

Received Thanks: 0

great explanation, I really appreciate your help.

edit:
My hook is still crashing my game client just after ‘printf’ is being executed by now I got a point.

cAddict is offline

 

Old
11/17/2011, 21:48

 
#6

link

 

link's Avatar

 

elite*gold: 1

The Black Market: 0/0/0

Join Date: Jul 2005

Posts: 553

Received Thanks: 451

oops.. having a naked function with neither prologue nor epilogue and using local variable doesn’t make sense..
The prologue actually adjusts esp and makes room for the local variables, thus declaring the function as naked but trying to access local variables is erroneous, didn’t think of it..

Code:

char chCooldownInfo[] = "Cooldown value: %dn";

void Naked NewCooldown()
{
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [dwCooldown], EAX
		MOV [ECX+0x20], EAX

		PUSH EAX
		PUSH OFSSET chCooldownInfo
		CALL dword ptr [printf]

		ADD ESP,4*2

		RETN 4
	}
}

or

Code:

void NewCooldown(int param)
{
	char chCooldownInfo[] = "Cooldown value: %dn";
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [dwCooldown], EAX
		MOV [ECX+0x20], EAX
	}
	printf(chCooldownInfo, dwCooldown);
}

hope this finally works…

link is offline

 

Thanks

1 User

Old
11/17/2011, 22:38

 
#7

cAddict

 

elite*gold: 0

The Black Market: 0/0/0

Join Date: Nov 2011

Posts: 6

Received Thanks: 0

thank you for another educating reply.

however, first example cause an error in my compiler:

Code:

error C2400: inline assembler syntax error in 'first operand'; found 'newline'

and second one cause an engine crash at offset ‘NewCooldown+46’:

Code:

NewCooldown   - 83 EC 18              - sub esp,18
NewCooldown+3 - A1 00B00010           - mov eax,[__security_cookie]
NewCooldown+8 - 33 C4                 - xor eax,esp
NewCooldown+A - 89 44 24 14           - mov [esp+14],eax
NewCooldown+E - A1 60510010           - mov eax,[`string']
NewCooldown+13 - 8B 0D 64510010       - mov ecx,[`string'+4]
NewCooldown+19 - 8B 15 68510010       - mov edx,[`string'+8]
NewCooldown+1F - 89 04 24             - mov [esp+esp],eax
NewCooldown+22 - A1 6C510010          - mov eax,[`string'+C]
NewCooldown+27 - 89 4C 24 04          - mov [esp+04],ecx
NewCooldown+2B - 8B 0D 70510010       - mov ecx,[`string'+10]
NewCooldown+31 - 89 54 24 08          - mov [esp+08],edx
NewCooldown+35 - 89 44 24 0C          - mov [esp+0C],eax
NewCooldown+39 - 89 4C 24 10          - mov [esp+10],ecx
NewCooldown+3D - 8B 44 24 04          - mov eax,[esp+04]
NewCooldown+41 - A3 A0B80010          - mov [dwCooldown],eax
NewCooldown+46 - 89 41 20             - mov [ecx+20],eax   // this is the place that cause a crash
NewCooldown+49 - 8B 15 A0B80010       - mov edx,[dwCooldown]
NewCooldown+4F - 52                   - push edx
NewCooldown+50 - 8D 44 24 04          - lea eax,[esp+04]
NewCooldown+54 - 50                   - push eax
NewCooldown+55 - FF 15 A8500010       - call dword ptr [_imp__printf]
NewCooldown+5B - 8B 4C 24 1C          - mov ecx,[esp+1C]
NewCooldown+5F - 83 C4 08             - add esp,08
NewCooldown+62 - 33 CC                - xor ecx,esp
NewCooldown+64 - E8 AD300000          - call __security_check_cookie
NewCooldown+69 - 83 C4 18             - add esp,18
NewCooldown+6C - C3                   - ret

this asm code looks strange to me and its even more confusing
maybe this code is erasing some important registers?

maybe I should tell you few words on how this native function works

Code:

006952E9 - 8B 44 24 04                - mov eax,[esp+04]
006952ED - 89 41 20                   - mov [ecx+20],eax
006952F0 - C2 0400                    - ret 0004

// eax = 1140735489, 1144036829, and so on.

eax contains something like a timestamp+skill charge+cooldown, so game will know how long the cooldown should last.

these values are different from the one I can get by GetTickCount but every time I use skill value is increased by same amount:
current timestamp + (skill charge time + skill cooldown time)

now, if I patch this function like this:

Code:

006952E9 - C7 41 20 01000000          - mov [ecx+20],00000001
006952F0 - C2 0400                    - ret 0004

then it works perfectly and I get no cooldown at all so I can spam teens/houndreds of skills in a second.

The problem is this ‘plain stupid patching’ method does not satisfy me anymore and I want to learn something more ‘sufisticated’

edit:
I have succeded to stop my game from getting a crash by ‘PUSHAD/POPAD’ — saving and restoring registers, so my code looks like this:

Code:

void Naked NewCooldown()
{
	__asm
	{
		MOV EAX, [ESP+0x04]
		MOV [ECX+0x20], EAX

		PUSH EAX
		MOV EAX, OFFSET info
		PUSH EAX

		PUSHAD
		CALL DWORD PTR [printf]
		POPAD

		ADD ESP, 0x08

		RETN 4
	}
}

but something must be wrong because instead of «cooldown value: %d» I get this:

Code:

�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(
~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�
(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~
�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(~�(
~�(~�(~�(~�(~�(~�(~�(~�Ć}�Ć}�Ć}�Ć}�Ć}�Ć}�Ć}�Ć}�Ć}�Ć}�Ć}�Ć}�Ć}
cAddict is offline

 

Reply

«
XTrap detection omg
|
aimbot + autoshoot
»

Similar Threads
Similar Threads

i bot run time error 13 type mimatch

01/17/2011 — Silkroad Online — 2 Replies

i use i bot now for 3 days they send me some scripts at temple job cave with the scripts that they do the quest and then it finish it … i go there it picking up the quest go at the training place it goes ba ck to turn in the quest BUT WHEN IT GOES BA CK AGAIN AT TRAINING PLACE AT THE SPOT I GET THE ERROR MSG »RUN TIME ERROR 13 TYPE MISMATCH» can someone pls help me with this i will be very appriciate it
thank you !


[Ribot] Error 13 type mismatch

02/05/2010 — Silkroad Online — 2 Replies

If got the ‘error 13 type mismatch’. I didn’t got it before but I logged in to my char (I normally use clientless) and then I wanted to do clientless again and it gives that error. When I try to use bot + client it says error 6 overflow.
I tried to install the ocx files again and reinstalled the bot. Still doesn’t work!
Anybody got the answer for this?
Thanks in advance!


Error Code6 Type 412

11/20/2009 — Cabal Online — 5 Replies

i am search and search
Cabal update and now comes
Error Code6 Type 412 wenn iam loging in
i get cabalrider but in the forum nothing for this error
have everybody the same error Code
what can i do


Have you experienced Error Code: 6 Type: 421 ?

06/17/2009 — Cabal Online — 2 Replies

Have you experienced Error Code: 6 Type: 421? Any known solutions for this one — whitout having to re-install the game?
Thanks


Different type of error

04/09/2009 — Aion — 4 Replies

after installing both the torrent version and the multiple files from the chinese site this is the error i recieve after i click (Y) to install.
http://img19.imageshack.us/img19/5062/75705188.jp g
im useing vista x64 with all drivers updated.
Now i did try the English clients offered in the FAQ thread, and it installs fine. but that’s not for the chinese open beta. Can anyone give me a hand here?

All times are GMT +1. The time now is 13:12.

Quick Style Chooser Quick Language Chooser


elitepvpers — play less, get more —
Top

Powered by vBulletin®
Copyright ©2000 — 2023, Jelsoft Enterprises Ltd.

SEO by vBSEO ©2011, Crawlability, Inc.

This site is protected by reCAPTCHA and the Google
Privacy Policy and
Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2023 elitepvpers All Rights Reserved.

 

Понравилась статья? Поделить с друзьями:
  • Error c2338 windows headers require the default packing option
  • Error c231 redefinition
  • Error c2259 невозможно создать экземпляр абстрактного класса
  • Error c2248 cannot access private member declared in class
  • Error c2238 непредвиденные лексемы перед