我在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;
}
任何人都能指出我做错了什么吗?
答案 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;
}
实现。它还会读取偶数长度字符串的结尾,如果超过字符串结尾的字节未映射到内存中,则会导致内存错误。