我在C++中有内联汇编问题。我正在尝试实现快速strlen,但是它不起作用-当我使用__declspec(naked)关键字调试器时,显示的输入地址为0x000000,当我不使用该关键字时,eax指向一些垃圾,函数返回各种值。

这是代码:

   int fastStrlen(char *input) // I know that function does not calculate strlen
{                              // properly, but I just want to know why it crashes
    _asm                       // access violation when I try to write to variable x
    {
        mov ecx, dword ptr input
            xor eax, eax
        start:
            mov bx, [ecx]
            cmp bl, '\0'
            je Sxend
            inc eax
            cmp bh, '\0'
            je Sxend
            inc eax
            add ecx, 2
            jmp start
        Sxend:
            ret
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    char* test = "test";
    int x = fastStrlen(test);
    cout << x;
    return 0;
}

有人可以指出我做错了什么吗?

最佳答案

不要使用__declspec(naked),因为在这种情况下,编译器不会生成结尾和序言指令,并且您需要生成一个序言,就像编译器希望您访问参数fastStrlen一样。由于您不知道编译器期望什么,您应该让它生成序言。

这意味着您不能只使用ret返回给调用者,因为这意味着您要提供自己的尾声。由于您不知道编译器使用了什么序言,因此也不知道需要使用什么结尾来反转它。而是将返回值分配给您在内联汇编语句之前在函数内部声明的C变量,并在常规C return语句中返回该变量。例如:

int fastStrlen(char *input)
{
    int retval;
    _asm
    {
        mov ecx, dword ptr input
        ...
    Sxend:
        mov retval,eax
    }
    return retval;
}

如您的注释中所述,您的代码将无法改善编译器运行时库中的strlen实现。它还会读取超过偶数长度的字符串末尾,如果未将字符串末尾的字节映射到内存中,则会导致内存错误。

07-26 09:11