C / C ++内联asm不正确的操作数类型

时间:2016-06-15 21:30:07

标签: c++ c visual-c++ assembly x86

我有以下代码,应该对一块内存进行异或运行:

void XorBlock(DWORD dwStartAddress, DWORD dwSize, DWORD dwsKey)
{
DWORD dwKey;
__asm
{
    push eax
    push ecx
    mov ecx, dwStartAddress          // Move Start Address to ECX
    add ecx, dwSize                  // Add the size of the function to ECX
    mov eax, dwStartAddress          // Copy the Start Address to EAX

    crypt_loop:                         // Start of the loop
        xor byte ptr ds:[eax], dwKey     // XOR The current byte with 0x4D
        inc eax                         // Increment EAX with dwStartAddress++
        cmp eax,ecx                     // Check if every byte is XORed
    jl crypt_loop;                      // Else jump back to the start label

    pop ecx // pop ECX from stack
    pop eax // pop EAX from stack
}
}

但是,参数dwKey给了我一个错误。如果例如dwKey被0x5D替换,则代码可以正常工作。

1 个答案:

答案 0 :(得分:4)

我认为你有两个问题。

首先,“xor”不能占用两个内存操作数(ds:[eax]是内存位置,dwKey是内存位置);其次,您使用“byte ptr”来表示您想要一个字节,但是您尝试使用DWORD并且程序集无法自动转换它们。

因此,您可能需要将值加载到8位寄存器中,然后执行此操作。例如:

void XorBlock(DWORD dwStartAddress, DWORD dwSize, DWORD dwsKey)
{
    DWORD dwKey;
    __asm
    {
        push eax
        push ecx
        mov ecx, dwStartAddress          // Move Start Address to ECX
        add ecx, dwSize                  // Add the size of the function to ECX
        mov eax, dwStartAddress          // Copy the Start Address to EAX
        mov ebx, dwKey                   // <---- LOAD dwKey into EBX

        crypt_loop :                         // Start of the loop
            xor byte ptr ds : [eax], bl     // XOR The current byte with the low byte of EBX
            inc eax                         // Increment EAX with dwStartAddress++
            cmp eax, ecx                     // Check if every byte is XORed
            jl crypt_loop;                      // Else jump back to the start label

        pop ecx // pop ECX from stack
        pop eax // pop EAX from stack
    }
}

虽然看起来dwKey在您的代码中未初始化;也许你应该只是“mov bl,0x42”。我也不确定你是否需要推动和弹出寄存器;我不记得哪些寄存器允许使用MSVC ++内联汇编程序。

但是,最后,我认为Alan Stokes的评论是正确的:在这种情况下,汇编实际上不可能比C / C ++代码更快。编译器可以轻松地自己生成这些代码,您可能会发现编译器实际上进行了意外的优化,使其运行速度比“明显”的汇编更快(例如,loop unrolling)。