gcc编译器对memcpy的优化

本文探讨了在CPPUTEST框架下,通过在makefile中加入-fno-builtin参数来确保memcpy函数调用桩函数实现而非依赖C库的情况。通过分析汇编代码,揭示了编译器如何对memcpy进行优化,以及这种优化如何影响C++单元测试的执行过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  最近在CPPUTEST框架下写单元测试程序,测试用例对于memcpy打桩(即定义一个本地的memcpy,不链接到C库的memcpy)。

  函数原型如下:

void *memcpy(void *dest, const void *src, size_t n)

{

    printf("this is my stub\n");

}

  运行的时候,发现size_t 如果是一个变量,或者一个比较大的值,printf会执行。如果size_t是一个小于120的数,printf不会被执行。开始的时候,以为是C++函数重载导致的。结果在本地并没有发现memcpy的其他定义。用了objdump出来看汇编。发现一个有意思的现象,如下:

void fun(char const * const filename)
{
  char *aa = NULL;
  406f54: 48 c7 45 f0 00 00 00 movq   $0x0,0xfffffffffffffff0(%rbp)
  406f5b: 00 
  char *bb =NULL;
  406f5c: 48 c7 45 f8 00 00 00 movq   $0x0,0xfffffffffffffff8(%rbp)
  406f63: 00 
    
  (void)memcpy((void *)aa, (const void *)bb, 1024*1024);
  406f80: 48 8b 45 f0           mov    0xfffffffffffffff0(%rbp),%rax
  406f84: 48 8b 55 f8           mov    0xfffffffffffffff8(%rbp),%rdx
  406f88: 48 89 c7             mov    %rax,%rdi
  406f8b: 48 89 d6             mov    %rdx,%rsi
  406f8e: ba 00 00 10 00       mov    $0x100000,%edx
  406f93: e8 f2 c0 ff ff       callq  40308a <memcpy>
  406f98: 48 8b 05 09 f3 22 00 mov    2290441(%rip),%rax
  406f9f: 48 83 c0 01           add    $0x1,%rax
  406fa3: 48 89 05 fe f2 22 00 mov    %rax,2290430(%rip)
    (void)memcpy((void *)aa, (const void *)bb,  1);
  406fc6: 48 8b 55 f0           mov    0xfffffffffffffff0(%rbp),%rdx
  406fca: 48 8b 45 f8           mov    0xfffffffffffffff8(%rbp),%rax
  406fce: 0f b6 00             movzbl (%rax),%eax
  406fd1: 88 02                 mov    %al,(%rdx)
  406fd3: 48 8b 05 de f2 22 00 mov    2290398(%rip),%rax
  406fda: 48 83 c0 01           add    $0x1,%rax
  406fde: 48 89 05 d3 f2 22 00 mov    %rax,2290387(%rip)


  return EAaTrblCbStatus_Ok;
  406fe5: b8 00 00 00 00       mov    $0x0,%eax

}

可以看到,编译器对于第二次的memcpy做了优化,不调用memcpy函数,就直接做了内存拷贝。

百度了下,发现如下链接说的比较详细了。

http://blog.sina.com.cn/s/blog_4017fe890100hat2.html

在单元测试的makefile中加入-fno-builtin参数。终于如愿以偿了,每次测试case,都调用了memcpy桩函数。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值