Search code examples
c++assemblyvisual-studio-2019masm

Error C2420 : illegal symbol in first operand


I have this code, I am using Visual Studio 2019. Compiler gives the error: Error C2420 'less': illegal symbol in first operand

#include <iostream>
using namespace std;
int a, b, c, d, x;
int values[5]; // масив для збереження у(х)
void main() {
a = -6; b = 4; c = 8; d = 2;
__asm {
    mov eax, offset values
    push eax 
    mov cx, 5 
    start: 
        mov ax, 3 
        sub ax, cx 
        cwde 
        mov ebx, eax 
        mov eax, a 
        cmp ebx, 1 
        jl less // if х < 1, go to less
        je equals //if х == 1, go to equals

        // if х > 1:

        imul eax // a^2
        sub eax, ebx // a^2-x
        cdq 
        mov ebx, c 
        idiv ebx // (a^2-x)/c
        jmp result 

    less :
        mov edx, 2
        imul edx // a*2
        imul ebx // a*2*x
        add eax, 5 // a*2*x+5
        jmp result 
    equals :
        mov ebx, b 
        sub eax, ebx // a-b
        cdq 
        mov ebx, d 
        idiv ebx // (a-b)/d
        jmp result 
    result :
        pop ebx 
        mov[ebx], eax 
        add ebx, 4 
        push ebx 
        loop start 
}
for (int i = 0; i < 5; i++) {
    cout << values[i] << endl;
}
system("pause");
}

The compiler gives error because of this line:

jl less

Without it, the code works. But I need this line, how to fix this?


Solution

  • You have included the entire std namespace into the local namespace by the line:

    using namespace std;
    

    The problem with this is that std namespace includes function objects (class templates) std::less, std::greater_equal, etc that are used for comparisons.

    Since std::less has been pulled into the local namespace, the MSVC inline assembly code you have used is confused as it thinks you are trying to jmp to the label less from the std namespace and not the label less further in your inline assembly code.

    The proper fix is to remove this line:

    using namespace std;
    

    It is bad practice to include the entire std namespace. Removing the line above will require changing this line:

    cout << values[i] << endl;
    

    to:

    std::cout << values[i] << std::endl;
    

    Alternatively you can replace using namespace std; with:

    using std::cout;
    using std::endl;
    

    This will only include these two items into the local name space.