前言

 

同样是一个 很常用的 glibc 库函数 

不管是 用户业务代码 还是 很多类库的代码, 基本上都会用到 内存数据的比较  

不过 我们这里是从 具体的实现 来看一下 

它的实现 主要是使用 汇编 来进行实现的, 因此 理解需要一定的基础 

测试用例

就是简单的使用了一下 memcpy, memset, memcmp 

#include "stdio.h"
 
int main(int argc, char** argv) {
 
int x = 2;
int y = 3;
int z = x + y;
 
void *p1 = malloc(20);
void *p2 = malloc(20);
void *p3 = malloc(20);
printf("p1 : 0x%x\n", p1);
printf("p2 : 0x%x\n", p2);
printf("p3 : 0x%x\n", p3);
 
memset(p1, 'a', 12);
memcpy(p2, p1, 17);
int p1CmpResult = memcmp(p1, p2); 
 
printf(" x + y = %d, p1CmpResult = %d\n ", z, p1CmpResult);
 
}

memcmp 的实现

这里 因为库程序里面没有调用 memcpy, 另外 用户代码中的 memcpy 没有调用到 x86_64 的 memcpy 的实现 

因此, 这里 直接看相关实现  

分为 32 字节以上, 的处理 和 32 字节一下的处理 

24 memcmp 的调试_linux

对于 小于32字节 的场景, 注意这里 si 为 (si - di) 表示的是 源地址 和 目标地址的偏移 

这里的道理和 memcpy 的调试 中的 "32 以下的数字" 处理类似, 来依次比较这 1, 2, 4, 8, 16 个字节的数据, 处理 32 字节, 其中某一部分字节比较出结果 直接返回 

24 memcmp 的调试_glibc_02

对于长度大于 32字节 的场景 

按 16/32 字节为为单位进行比较, 如果比较出结果 直接返回 

PCMPEQB/PCMPEQW/PCMPEQD — Compare Packed Data for Equal

PMOVMSKB — Move Byte Mask

24 memcmp 的调试_glibc_03