简体   繁体   English

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

[英]C++ Passing arguments to inline assembler function

I have problem with inline asm in C++. 我在C ++中有内联汇编问题。 I'm trying to implement fast strlen, but it is not working - when I use __declspec(naked) keyword debugger shows address of input as 0x000000, when I don't use that keyword, eax is pointing for some trash, and function returns various values. 我正在尝试实现快速strlen,但是它不起作用-当我使用__declspec(naked)关键字调试器时,输入的地址显示为0x000000,当我不使用该关键字时,eax指向一些垃圾,函数返回各种价值。

Here's code: 这是代码:

   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;
}

can anybody point me out what am I doing wrong? 有人可以指出我做错了什么吗?

Don't use __declspec(naked) since in that case the complier doesn't generate epilogue and prologue instructions and you need to generate a prologue just like compiler expects you to if you want to access the argument fastStrlen . 请勿使用__declspec(naked)因为在这种情况下,编译器不会生成结尾和序言指令,并且您需要生成一个序言,就像编译器希望访问fastStrlen参数fastStrlen Since you don't know what the compiler expects you should just let it generate the prologue. 由于您不知道编译器期望什么,您应该让它生成序言。

This means you can't just use ret to return to the caller because this means you're supplying your own epilogue. 这意味着您不能只使用ret返回到呼叫者,因为这意味着您要提供自己的结尾。 Since you don't know what prologue the compiler used, you don't know what epilogue you need implement to reverse it. 由于您不知道编译器使用了什么序言,因此您不知道需要实现什么尾声来反转它。 Instead assign the return value to a C variable you declare inside the function before the inline assembly statement and return that variable in a normal C return statement. 而是将返回值分配给您在内联汇编语句之前在函数内部声明的C变量,并在常规C return语句中返回该变量。 For example: 例如:

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

As noted in your comments your code will not be able to improve on the strlen implementation in your compiler's runtime library. 如您的注释中所述,您的代码将无法改善编译器运行时库中的strlen实现。 It also reads past the end of strings of even lengths, which will cause a memory fault if the byte past the end of a string isn't mapped into memory. 它也会读取偶数长度的字符串末尾,如果未将字符串末尾的字节映射到内存中,则会导致内存错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM