如何让GCC编译器生成REPE CMPSB指令(纯C实现)
如何用纯C代码让GCC生成REPE CMPSB指令?
嘿,我来帮你搞定这个问题!你写的那段循环代码逻辑上和REPE CMPSB做的事差不多,但GCC没把它优化成REPE CMPSB,其实是因为编译器没法确定你的指针有没有重叠,而且循环里的操作太“散”,没触发针对字符串指令的优化。
先看看你原来的代码:
unsigned int repe_cmpsb(unsigned char *esi, unsigned char *edi, unsigned int ecx) { for (; ((*esi == *edi) && (ecx != 0)); esi++, edi++, ecx--); return ecx; }
调整后的可行代码
要让编译器认出这是字符串比较的模式,你需要给它足够的提示,比如用restrict关键字消除指针重叠的顾虑,同时调整循环结构匹配REPE CMPSB的执行逻辑:
unsigned int repe_cmpsb(unsigned char *restrict esi, unsigned char *restrict edi, unsigned int ecx) { while (ecx != 0 && *esi == *edi) { esi++; edi++; ecx--; } return ecx; }
为什么这样能生成REPE CMPSB?
restrict关键字:它告诉编译器esi和edi指向的内存区域完全不重叠,编译器不用考虑内存重叠带来的副作用,可以放心地用字符串指令进行优化,不用保留逐字节循环的保守逻辑。- 循环逻辑匹配:REPE CMPSB的执行顺序是先检查计数寄存器(ECX)不为0,再比较ESI和EDI指向的字节,相等则继续循环。调整后的
while循环先判断ecx != 0再比较字节,和指令的语义完全对齐,GCC的字符串优化器能直接识别这个模式,生成对应的REPE CMPSB指令。
如果你的指针是对齐的(比如按字节或更高对齐),还可以添加__builtin_assume_aligned来进一步优化,但注意这属于编译器内建函数,你要求不能用的话可以忽略,上面的代码已经足够触发目标指令了。
内容的提问来源于stack exchange,提问作者George Robinson
相关产品推荐
相关产品推荐

