Search code examples
cvisual-c++x86inline-assembly

Why does using QWORD in MSVC give an "invalid operand type" error?


I am learning elementary in-line assembly for self-intrest, and was playing around with defining some load-in-memory instructions. After figuring out how to transfer a byte (defined as a char) array to a differently sized variable using the line mov [size] ptr [Memory], I did some test runs. byte ptr, word ptr, and dword ptr worked great. However, the assembly code to load a qword, or QWORD ptr always gives me a an error that says "invalid operand type". Why is this?

Here are my macro definitions:

//x86, MSVC, Visual Studio.
typedef signed char byte;
#pragma region Instructions
// ldb - load byte
#define ldb(reg, mem) __asm { \
    __asm mov al, byte ptr mem \
    __asm mov reg, al \
}
// ldw - load word
#define ldw(reg, mem) __asm { \
    __asm mov ax, WORD PTR mem \
    __asm mov reg, ax \
}
// ldq - load double
#define ldq(reg, mem) __asm { \
    __asm mov eax, DWORD PTR mem \
    __asm mov reg, eax \
}
// ldo - load quad
#define ldo(reg, mem) __asm { \
    __asm mov rax, QWORD PTR mem \
    __asm mov reg, rax \
}
#pragma endregion

And here is my testing code:

int main() {
    byte test_memory[1000] = { 0 }; // don't worry about other 999 indexes.
    test_memory[0] = 0x12;;

    byte reg = 0;
    // load byte
    ldb(reg, test_memory[0]);
    printf("ldb: %x\n", reg); // prints 0x12
    // load word
    word reg2 = 0;
    ldw(reg2, test_memory[0]);
    printf("ldw: %x\n", reg); // prints 0x12
    // load double
    dword reg3 = 0;
    ldq(reg3, test_memory[0]); // prints 0x12
    printf("ldq: %x\n", reg);
    // load quad
    qword reg4 = 0;
    ldo(reg4, test_memory[0]); // error!!!
    printf("ldo: %x\n", reg);
    return 0;
}

If there is something I am missing here, any help would be much appriceated.


Solution

  • As said the comments, I was trying to access rax in a 32-bit environment. Oops!