【发布时间】:2012-03-10 12:29:25
【问题描述】:
有人能解释一下为什么我的 strcat 会这样做吗?
我似乎不知道为什么要重写源字符串的一部分。
输出如下: New String: HelloThis shall be after my backslash 0 in str1h 0 in str1
global strcat
extern strlen
strcat:
push ebp
mov ebp, esp
push ecx
push esi
push edi
push ebx
push edx
xor edx, edx
xor edi, edi
xor ebx, ebx
xor esi, esi
xor ecx, ecx
mov edi, [ebp + 8]
mov esi, [ebp + 12]
push edi
call strlen
pop edi
mov ecx, eax
xor eax, eax
push esi
call strlen
pop esi
mov ebx, eax
xor eax, eax
cmp [edi + ecx], byte 0b
je PUT_LINE
jmp FINALIZE_END
PUT_LINE:
cmp ebx, eax
je END
mov dl, [esi + eax]
mov [edi + ecx], dl
xor edx, edx
inc eax
inc ecx
jmp PUT_LINE
结束:
mov eax, [ebp + 8]
jmp FINALIZE_END
FINALIZE_END:
pop edx
pop ebx
pop edi
pop esi
pop ecx
mov esp, ebp
pop ebp
ret
~
~
int main(int argc, char** argv)
{
(void)argc;
(void)argv;
char* str1;
char* str2;
str1 = strdup("Hello");
str2 = strdup("This shall be after my backslash 0 in str1");
printf("New String : %s\n", strcat(str1, str2));
return (0);
}
~
【问题讨论】:
-
对不起,我刚刚解决了,看起来 Printf 也在寻找 \0,但是因为我没有在目标字符串的末尾设置 \0,所以它溢出了。 END: mov [edi + ecx], byte 0b mov eax, [ebp + 8] jmp FINALIZE_END
-
在加载寄存器之前将寄存器归零有点违背了编写 asm 的目的......
-
我只是想避免在使用 8 位还是 16 位时遇到问题,并猜测这是一个坏习惯,但感谢您的间接建议。
-
看起来您正在保存和恢复的大多数寄存器都不需要保存或恢复。至少在标准的 x86 abi 上,只有 ebp、esi、edi 和 ebx 是被调用者保存的,如果你不使用它们,就不需要保存它们。也不需要在 ebp 中设置帧指针;只需使用 esp 相对寻址。在您进行这样的更改之前,您的
strcat几乎肯定会比短字符串上的标准慢很多,因为进入/退出开销很高。当然,即使你优化得很好,它可能仍然不会更快,但至少你学到了一些好的技巧。
标签: c assembly x86 nasm strcat