为何GCC编译的代码调用memmove而非memcpy?
问题
在Linux系统使用GCC 12.2编译器,添加-nostdlib参数编译时,编译器提示缺少memcpy和memmove。我用汇编实现了一个简易memcpy,同时让memmove调用abort,目的是让代码始终使用memcpy。之后尝试用C实现自定义内存拷贝函数mymemcpy,通过#define memcpy mymemcpy替换标准memcpy,但运行时程序终止,发现GCC实际调用了memmove而非我实现的memcpy。Clang编译时会调用memcpy,但GCC的优化效果更好,我需要用它做优化构建。
可复现代码
dummy.cpp
extern "C" { void*malloc() { return 0; } int read() { return 0; } int write() { return 0; } int memcpy() { return 0; } int memmove() { return 0; } }
main.cpp
#include <unistd.h> #include <cstdlib> struct MyVector { void*p; long long position, length; }; __attribute__ ((access(write_only, 1))) __attribute__((nonnull(1, 2))) void mymemcpy(void *__restrict__ dest, const void *__restrict__ src, int size) { const unsigned char *s = (const unsigned char*)src; unsigned char *d = (unsigned char*)dest; while(size--) *d++ = *s++; } //__attribute__ ((noinline)) int func(const char*file_from_disk, MyVector*v) { if (v->position + 5 <= v->length ) { mymemcpy(v->p, file_from_disk, 5); } return 0; } char buf[4096]; extern "C" int _start() { MyVector v{malloc(1024),0,1024}; v.position += read(0, v.p, 1024-5); int len = read(0, buf, 4096); func(buf, &v); write(1, v.p, v.position); }
编译命令
g++ -march=native -nostdlib -static -fno-exceptions -fno-rtti -O2 main.cpp dummy.cpp
编译结果验证(objdump输出)
401040: e8 db 00 00 00 call 401120 <memmove> 40108d: e8 4e 00 00 00 call 4010e0 <malloc> 4010a3: e8 48 00 00 00 call 4010f0 <read> 4010ba: e8 31 00 00 00 call 4010f0 <read> 4010c5: e8 56 ff ff ff call 401020 <_Z4funcPKcP8MyVector> 4010d5: e8 26 00 00 00 call 401100 <write> 402023: ff 11 call *(%rcx)
内容的提问来源于stack exchange,提问作者Stan
相关产品推荐
相关产品推荐

