前言
同样是一个 很常用的 glibc 库函数
不管是 用户业务代码 还是 很多类库的代码, 基本上都会用到 字符串的复制
不过 我们这里是从 具体的实现 来看一下
它的实现 主要是使用 汇编 来进行实现的, 因此 理解需要一定的基础
测试用例
就是简单的使用了一下 strcpy, strlen
root@ubuntu:~/Desktop/linux/HelloWorld# cat Test03Strcpy.c
#include "stdio.h"
int main(int argc, char** argv) {
int x = 2;
int y = 3;
int z = x + y;
char* p1 = (char*) malloc(20);
char* p2 = (char*) malloc(20);
printf("p1 : 0x%x\n", p1);
printf("p2 : 0x%x\n", p2);
memset(p1, 'a', 12);
strcpy(p2, p1);
int p2Len = strlen(p2);
printf(" p1 = %s, p2 = %s, p2Len = %d\n ", p1, p2, p2Len);
}
strcpy 的实现
首先是根据 8 字节对齐, 处理对齐之后剩余的字节
这里的 label 0 的循环, 如果碰到 字符串结束字符, 跳转到 结束处理
然后 以 8 字节为单位, 每次循环 4 组 来进行数据的复制, 主要是 si -> ax -> di, 然后迭代更新 si, di
中间的两个 jnc, jnz 的这段逻辑处理主要是判断 当前这批 8 字节是否存在 字符串结束符 '\0'
如果存在, 则跳转到 label 3 的流程处理
否则 进行普通的 8 字节数据拷贝处理到目标内存
如果当前处理的 8 字节[存放于ax] 中存在 字符串结束符 '\0'
则 label 3 的处理就是按字节 从源内存拷贝到目标内存
然后 碰到 字符串结束符 '\t', 跳转到 label 4, 结束当前函数
完