我正在使用-O3 -x c -std=c99 -fno-builtin -nostdlib -ffreestanding
unsigned char *memset(unsigned char *dest, unsigned char val, int count)
{
unsigned char* p = dest;
while (count--)
*p++ = val;
return dest;
}
#include <stdio.h>
int main()
{
unsigned char c[20];
memset(c, 'a', 19);
c[19] = '\0';
printf((const char*) c);
}
并使用godbolt来检查gcc在程序集输出中调用的memset
。
memset:
test edx, edx
je .L6
sub edx, 1
sub rsp, 8
movzx esi, sil
add rdx, 1
call memset
add rsp, 8
ret
.L6:
mov rax, rdi
ret
main:
sub rsp, 40
movabs rax, 7016996765293437281
mov QWORD PTR [rsp], rax
mov QWORD PTR [rsp+8], rax
mov eax, 24929
mov WORD PTR [rsp+16], ax
mov rdi, rsp
xor eax, eax
mov BYTE PTR [rsp+18], 97
mov BYTE PTR [rsp+19], 0
call printf
add rsp, 40
ret
使用我使用过的标志,我试图消除它调用内置memset
的所有可能性,并根据彩色化神棒使用来判断,看起来gcc正在{{进行递归调用1}}。那么它是在进行递归还是调用内置*p++ = val;
?
答案 0 :(得分:1)
正如其他人所指出的,数组 c 元素的设置已经内联。结果,你实现的memset()甚至没有被调用。这是使用-03编译器选项的结果。编译器在优化方面非常积极。此外,执行路径上没有递归。
然而,这并不能完全回答你的问题。反汇编输出中显示的memset()确实不是内置版本,甚至没有被执行。
顺便说一下,您不需要应用-fno-builtin标志,因为-ffreestanding标志会自动隐含它。另外,如果启用垃圾收集,我相信会发现反汇编输出中的memset()例程将会消失。