前言
同样是一个 很常用的 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 字节一下的处理
对于 小于32字节 的场景, 注意这里 si 为 (si - di) 表示的是 源地址 和 目标地址的偏移
这里的道理和 memcpy 的调试 中的 "32 以下的数字" 处理类似, 来依次比较这 1, 2, 4, 8, 16 个字节的数据, 处理 32 字节, 其中某一部分字节比较出结果 直接返回
对于长度大于 32字节 的场景
按 16/32 字节为为单位进行比较, 如果比较出结果 直接返回
PCMPEQB/PCMPEQW/PCMPEQD — Compare Packed Data for Equal
PMOVMSKB — Move Byte Mask
完