C ++将参数传递给内联汇编程序函数

时间:2014-09-01 17:42:40

标签: c++ c assembly inline-assembly

我在C ++中使用内联asm有问题。我试图实现快速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;
}

任何人都能指出我做错了什么吗?

1 个答案:

答案 0 :(得分:1)

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

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

ret

如您的评论中所述,您的代码将无法改进编译器运行时库中的int fastStrlen(char *input) { int retval; _asm { mov ecx, dword ptr input ... Sxend: mov retval,eax } return retval; } 实现。它还会读取偶数长度字符串的结尾,如果超过字符串结尾的字节未映射到内存中,则会导致内存错误。