我在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
实现。它还会读取超过偶数长度的字符串末尾,如果未将字符串末尾的字节映射到内存中,则会导致内存错误。