- 论坛徽章:
- 0
|
刚才想了一下, 觉得gcc的确不可能把这个递归演算成“repnz scasb”,又试了一下无穷递归:fedora:~ baicj$ cat strlen.c
int strlen(char *p)
{
return strlen(p);
}
fedora:~ baicj$ gcc -S -masm=intel -O1 strlen.c
fedora:~ baicj$ cat strlen.s
.file "strlen.c"
.intel_syntax noprefix
.text
.globl strlen
.type strlen, @function
strlen:
push ebp
mov ebp, esp
push edi
mov edi, DWORD PTR [ebp+8]
mov eax, 0
mov ecx, -1
repnz scasb
not ecx
lea eax, [ecx-1]
pop edi
pop ebp
ret
.size strlen, .-strlen
.ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)"
.section .note.GNU-stack,"",@progbits
fedora:~ baicj$
奇怪,无穷递归也被解释成“repnz scasb”了,看来gcc的O1选项会把strlen当作替换成内置的字串算法,不知道算不算bug, 或者有别的参数可以设置?
O0和O2很正常:fedora:~ baicj$ cat strlen.c
int strlen(char *p)
{
return strlen(p);
}
fedora:~ baicj$ gcc -S -masm=intel -O0 strlen.c
fedora:~ baicj$ cat strlen.s
.file "strlen.c"
.intel_syntax noprefix
.text
.globl strlen
.type strlen, @function
strlen:
push ebp
mov ebp, esp
sub esp, 8
mov eax, DWORD PTR [ebp+8]
mov DWORD PTR [esp], eax
call strlen
leave
ret
.size strlen, .-strlen
.ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)"
.section .note.GNU-stack,"",@progbits
fedora:~ baicj$ gcc -S -masm=intel -O2 strlen.c
fedora:~ baicj$ cat strlen.s
.file "strlen.c"
.intel_syntax noprefix
.text
.p2align 4,,15
.globl strlen
.type strlen, @function
strlen:
push ebp
mov ebp, esp
.L2:
jmp .L2
.size strlen, .-strlen
.ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)"
.section .note.GNU-stack,"",@progbits
fedora:~ baicj$
回过头来看原来的字串算法,用O2还是可以把递归变成循环, 不知道算不算尾递归?
fedora:~ baicj$ cat strlen.c
int strlen(char *p)
{
return *p ? strlen(p+1)+1 : 0;
}
fedora:~ baicj$ gcc -S -masm=intel -O2 strlen.c
fedora:~ baicj$ cat strlen.s
.file "strlen.c"
.intel_syntax noprefix
.text
.p2align 4,,15
.globl strlen
.type strlen, @function
strlen:
push ebp
xor ecx, ecx
mov ebp, esp
mov edx, 1
push ebx
mov ebx, DWORD PTR [ebp+8]
cmp BYTE PTR [ebx], 0
je .L3
.p2align 4,,7
.p2align 3
.L6:
movzx eax, BYTE PTR [ebx+edx]
mov ecx, edx
add edx, 1
test al, al
jne .L6
.L3:
mov eax, ecx
pop ebx
pop ebp
ret
.size strlen, .-strlen
.ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)"
.section .note.GNU-stack,"",@progbits
fedora:~ baicj$ |
|