Ошибка компилятора c2400

Here is the (almost 1:1) working code you posted for a standalone assembly.

binsearch.cpp

extern "C"
{
    bool BinSearch(int searchNum, int myArray[], int arraySize);
};

// This is the inlined version.
bool BinSearchInline(int searchNum, int myArray[], int arraySize)
{
    int middle;
    int first;
    int last;
    char found;

    _asm
    {
     push        ebx  
     push        esi  
     push        edi  

     mov         first,0  
     mov         eax, arraySize
     sub         eax,1  
     mov         last ,eax  
     mov         found,0

LocalLoop:

     mov         eax, first
     cmp         eax, last
     jg          NotFound

     mov         eax, first

     add         eax, last
     cdq  
     sub         eax,edx  
     sar         eax,1  
     mov         middle,eax  

     mov         eax,middle
     mov         ecx,myArray
     mov         edx,searchNum
     cmp         edx, dword ptr [ecx+eax*4]  
     jle         MaybeLower

     mov         eax, middle
     add         eax,1  
     mov         first, eax  
     jmp         WhileLoop

MaybeLower:
     mov         eax, middle
     mov         ecx, myArray
     mov         edx, searchNum
     cmp         edx,dword ptr [ecx+eax*4]  
     jge         Found

     mov         eax, middle
     sub         eax,1  
     mov         last, eax  

     jmp         WhileLoop

Found:
     mov         al,1
     jmp         Done

WhileLoop:
     jmp         LocalLoop

NotFound:
     xor         al,al  

Done:
     pop         edi  
     pop         esi  
     pop         ebx  
    };
}

int main(int argc, char*arg[])
{
    int testvalues[7];
    for(int i = 0; i < 7; i++)
        testvalues[i] = i;

    bool b = BinSearch(8, testvalues, 7);       // false, value not in array
    b = BinSearch(3, testvalues, 7);        // true, value is in array.

    b = BinSearchInline(8, testvalues, 7);      // false
    b = BinSearchInline(3, testvalues, 7);      // true

    return 0;
}

binsearch.asm

.486
.model flat, C
option casemap :none

.code

BinSearch PROC, searchNum:DWORD, myArray:PTR DWORD, arraySize:DWORD

    LOCAL first:DWORD
    LOCAL middle:DWORD
    LOCAL last:DWORD
    LOCAL found:BYTE

     push        ebx  
     push        esi  
     push        edi  

    ; This block is only for debugging stack errors and should be removed.
    ; lea         edi,[ebp-0F0h]  
    ; mov         ecx,3Ch 
    ; mov         eax,0CCCCCCCCh 
    ; rep stos    dword ptr es:[edi] 

     mov         dword ptr [first],0  
     mov         eax,dword ptr [arraySize]
     sub         eax,1  
     mov         dword ptr [last],eax  
     mov         byte ptr [found],0     ; not even used.

@@Loop:
     mov         eax,dword ptr [first]
     cmp         eax,dword ptr [last] 
     jg          @@NotFound

     mov         eax,dword ptr [first]

     add         eax,dword ptr [last]
     cdq  
     sub         eax,edx  
     sar         eax,1  
     mov         dword ptr [middle],eax  

     mov         eax,dword ptr [middle]  
     mov         ecx,dword ptr [myArray]  
     mov         edx,dword ptr [searchNum]  
     cmp         edx,dword ptr [ecx+eax*4]  
     jle         @@MaybeLower

     mov         eax,dword ptr [middle]  
     add         eax,1  
     mov         dword ptr [first],eax  
     jmp         @@WhileLoop

@@MaybeLower:
     mov         eax,dword ptr [middle]  
     mov         ecx,dword ptr [myArray]  
     mov         edx,dword ptr [searchNum]  
     cmp         edx,dword ptr [ecx+eax*4]  
     jge         @@Found

     mov         eax,dword ptr [middle]  
     sub         eax,1  
     mov         dword ptr [last],eax  

     jmp         @@WhileLoop

@@Found:
     mov         al,1
     jmp         @@Done

@@WhileLoop:
     jmp         @@Loop

@@NotFound:
     xor         al,al  

@@Done:
     pop         edi  
     pop         esi  
     pop         ebx  

     ret  

BinSearch ENDP

END

Причина, по которой это не работает, заключается в том, что __asm это ключевое слово, так же, как int является ключевым словом, оно не может появляться само по себе и должно следовать правильному синтаксису. Возьмем следующий фрагмент кода в качестве примера:

int main()
{
int      // here's a comment, but it's ignored by the compiler
return 0;
}

Следующий код потерпит неудачу с ошибкой компиляции, более конкретно в VS2012 вы получите error C2143: syntax error : missing ';' before 'return', Это очевидная ошибка, поскольку у нас нет конечной точки с запятой для обозначения конца инструкции; добавьте точку с запятой, и она прекрасно скомпилируется, потому что мы не нарушали синтаксис языка C (или C ++ в данном случае):

int main()
{
int      // here's a comment, but it's ignored by the compiler
; // white space and comments are ignored by the compiler
return 0;
}

То же самое относится и к следующему коду:

int main()
{
__asm ; here's a comment but it's ignored

return 0;
}

Кроме здесь мы получаем ошибку error C2400: inline assembler syntax error in 'opcode'; found 'constant'потому что это лечит все после __asm Ключевое слово в качестве инструкции на ассемблере, и комментарий по праву игнорируется .. поэтому будет работать следующий код:

int main()
{
__asm ; here's a comment but it's ignored
NOP ; white space and comments are ignored by the compiler

__asm {; here's an __asm 'block'
} // outside of __asm block so only C style comments work
return 0;
}

Так что это отвечает на ваш первый вопрос: Why didn't VS allow me to add an assembly comment?.. потому что это является синтаксическая ошибка.

Теперь для вашего второго вопроса: Is there a different way to add an assembly comment without adding an instruction, including NOP?

Прямо нет, нет, но косвенно да есть. Стоит отметить, что __asm Ключевое слово компилируется во встроенную сборку в вашей программе, поэтому комментарии будут удаляться из скомпилированной сборки так же, как если бы это был стандартный комментарий C / C ++, поэтому пытаться «принудительно» вызвать комментарий в вашей сборке с помощью этого метода, вместо этого , вы можете использовать /FAs флаг компилятора, и он сгенерирует сборку (машинный код), смешанную с исходным кодом, например:

Учитывая следующий (очень простой) код:

int main()
{
// here's a normal comment
__asm { ; here's an asm comment and empty block
} // here's another normal comment
return 0;
}

Когда скомпилировано с /FAs флаг компилятора file.asm было получено следующее:

; Listing generated by Microsoft (R) Optimizing Compiler Version 18.00.31101.0

TITLE   C:\test\file.cpp
.686P
.XMM
include listing.inc
.model  flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC  _main
; Function compile flags: /Odtp
; File c:\test\file.cpp
_TEXT   SEGMENT
_main   PROC

; 2    :     {

push    ebp
mov ebp, esp

; 3    :         // here's a normal comment
; 4    :         __asm { ; here's an asm comment and empty block
; 5    :         } // here's another normal comment
; 6    :         return 0;

xor eax, eax

; 7    :     }

pop ebp
ret 0
_main   ENDP
_TEXT   ENDS
END

Обратите внимание, как он включает в себя источник и комментарии. Если бы этот код сделал больше, вы бы увидели больше ассемблера и связанный с ним источник.

Если вы хотите поместить комментарии в саму встроенную сборку, то вы можете использовать обычные комментарии в стиле C / C ++, а также комментарии сборки внутри __asm сам блок:

int main()
{
// here's a C comment
__asm { ; here's an asm comment
// some other comments
NOP ; asm type comment
NOP // C style comment
} // here's another comment
return 0;
}

Надеюсь, что это может помочь.

РЕДАКТИРОВАТЬ:

Следует отметить, что следующий фрагмент кода также компилируется без ошибок, и я не уверен на 100%, почему:

int main()
{
__asm
__asm ; comment
// also just doing it on a single line works too: __asm __asm
return 0;
}

Компиляция этого кода с единственным __asm ; comment выдает ошибку компиляции, но с обоими компилирует нормально; добавление инструкций к приведенному выше коду и проверка .asm выход показывает, что второй __asm игнорируется для любых других команд сборки, предшествующих ему. Так что я не уверен на 100%, если это ошибка синтаксического анализа или часть __asm Синтаксис ключевого слова, так как нет документации по этому поведению.

2

0 / 0 / 0

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

Сообщений: 136

1

18.08.2016, 12:33. Показов 4328. Ответов 4


Студворк — интернет-сервис помощи студентам

visual studio выдал такую ошибку
error C2400: синтаксическая ошибка во встроенном коде на языке ассемблера в «код операции»; обнаружено «SHL».
что это значить?



0



1550 / 875 / 179

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

Сообщений: 2,555

18.08.2016, 12:45

2

Anette666k, Код в студию.



0



Anette666k

0 / 0 / 0

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

Сообщений: 136

18.08.2016, 14:46

 [ТС]

3

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "stdafx.h"
#include <iostream>
using namespace std;
void main()
{
int x, y = 0; //Объявляем целочисленные переменные x и y
cout << "x = ";
cin >> x;    //Считываем значение в переменную x
_asm
{
xor EAX, EAX //обнуляем регистр EAX xor EBX, EBX //обнуляем регистр EBX mov EAX, x   //EAX = x
mov EBX, 3   //EBX = 3
mul EBX      //EAX = EAX*EBX = 3*x
mov EBX, 9   //EBX = 9
add EAX, EBX //EAX = EAX + EBX = 3*x+9
mov y, EAX   //Записываем результат в y
}
cout << "y = " << y << endl; //Выводим результат на экран
}



0



obivan

Падаван С++

447 / 261 / 89

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

Сообщений: 916

18.08.2016, 14:58

4

Лучший ответ Сообщение было отмечено Anette666k как решение

Решение

Anette666k, ну судя по коментариям то вопервых код не так как надо будет работать потому что результат всегда будет 9

Assembler
1
2
3
xor EAX, EAX //обнуляем регистр EAX xor EBX, EBX //обнуляем регистр EBX mov EAX, x   //EAX = x
mov EBX, 3   //EBX = 3
mul EBX

потому что в коде сверху всегда 0
Теперь вопрос где компилируете, в vs2015 все норм скомпилировалось и результат как и должен быть 9

Добавлено через 2 минуты

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
void main()
{
    int x, y = 0; 
    cout << "x = ";
    cin >> x;    
    _asm
    {
        mov EAX, x 
        mov EBX, 3   
        mul EBX      
        mov EBX, 9   
        add EAX, EBX 
        mov y, EAX   
    }
    cout << "y = " << y << endl; 
}

вот вам код если хотите чтобы было решение на 3*x + 9



0



MansMI

Заблокирован

18.08.2016, 15:32

5

и кто тут SHL?



0



Я тестировал код С и наткнулся на эту странную
ошибка компилятора

Следующий код не будет компилировать

#include<stdio.h>
void main()
{
int length=6;
__asm
{
mov eax,length
}
}

Visual Studio сообщает о следующей ошибке

test.c(7) : error C2400: inline assembler syntax error in 'second operand'; 
found 'newline'

Однако я заметил, что если я изменил имя переменной на что-то еще, скажу lengths, тогда все было в порядке, следующий код компилируется без труда

#include<stdio.h>
void main()
{
int lengths=6;
__asm
{
mov eax,lengths
}
}

Я пробовал с другими компиляторами, такими как Digital Mars и Intel Compiler, но везде первый код не может быть скомпилирован.

В чем может быть проблема? Есть ли другое определение для length в другом месте.

Я также хотел бы добавить, что это один файл, а не проект, поэтому
не может быть никаких множественных объявлений.

Я тестировал код C и наткнулся на эту странную ошибку компилятора

Следующий код не компилируется

#include<stdio.h>
void main()
{
    int length=6;    
    __asm
    {
        mov eax,length
    }
}

Visual Studio сообщает о следующей ошибке

test.c(7) : error C2400: inline assembler syntax error in 'second operand'; 
found 'newline'

Однако я заметил, что если я изменил имя переменной на что-то еще, например lengths, тогда все было в порядке, следующий код компилируется без каких-либо проблем

#include<stdio.h>
void main()
{
    int lengths=6;    
    __asm
    {
        mov eax,lengths
    }
}

Я пробовал с другими компиляторами, такими как Digital Mars и Intel Compiler, но везде первый код не может быть скомпилирован.

В чем может быть проблема? Есть ли другое определение для length где-нибудь еще?

Я также хотел бы добавить, что это один файл, а не проект, поэтому не может быть нескольких объявлений.

2 ответа

Лучший ответ

См. Здесь: http://msdn.microsoft. com / en-US / library / wxh0awwe% 28v = vs.80% 29.aspx

В частности

Операторы LENGTH, SIZE и TYPE имеют ограниченное значение во встроенной сборке. Их вообще нельзя использовать с оператором DUP (потому что вы не можете определять данные с помощью директив или операторов MASM). Но вы можете использовать их для определения размера переменных или типов C или C ++:


7

Scotty Bauer
18 Ноя 2013 в 21:42

Я думаю, причина может быть в том, что length является функцией-членом

Также MSDN говорит:

Операторы LENGTH , SIZE и TYPE имеют ограниченное значение во встроенных сборка. Их вообще нельзя использовать с оператором DUP (т.к. вы не можете определять данные с помощью директив или операторов MASM). Но ты можешь используйте их, чтобы узнать размер переменных или типов C или C ++:

Оператор LENGTH может возвращать количество элементов в массиве. Это возвращает значение 1 для переменных, не являющихся массивом.


8

Rahul Tripathi
18 Ноя 2013 в 21:40

Понравилась статья? Поделить с друзьями:

Интересное по теме:

  • Ошибка компилятора c2371
  • Ошибка компилятора c2381
  • Ошибка компилятора c2361
  • Ошибка компилятора c2296
  • Ошибка компилятора c2220

  • Добавить комментарий

    ;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: