11 字符串操作指令 
1 字符串复制指令 
copy memcpy ( void   * t ,   void   * s ,   int   n ); 
memmove ( void   * t ,   void   * s ,   int   n ); 
strcpy ( char   * t ,   char   * s ); 
strncpy ( char   * t ,   char   * s ,   int   n );    // n 表示最多复制的字符数 
1.1 rep movsb 
从 ds:si 开始复制到 es:di,向前向后由 DF 决定,次数由 CX 决定
 
movsb 
1.1.1 Example 
example: 从左边复制到右边 
example mov   ax ,   1000 h 
mov   ds ,   ax 
mov   si ,   0    ; mov si, 3 
mov   ax ,   2000 h 
mov   es ,   ax 
mov   di ,   0    ; mov di, 3 
mov   cx ,   4 
cld          ; std 
rep   movsb 
Attention
si, di 一定会超出复制范围 1如果 cld,那么最终 si=di=4 
如果 std,那么最终 si=di=FFFF 
 
 
1.2 rep movsw 
一次复制一个 word
 
1.3 rep movsd 
同理,只是一次复制 4 个 byte
 
1.4 如果一次不是 4 个 byte 
在 32 位系统下,如果要复制的字节数 ecx 不是 4 的倍数,可以做下面这样的处理,相当于处理了最后几个
push   ecx 
shr   ecx ,   2 
rep   movsd 
pop   ecx 
and   ecx ,   3    ; 相当于 ecx = ecx % 4 
rep   movsb 
2 字符串比较指令 
2.1 cmpsb 
2.2 repe cmpsb 
若本次相等则继续比较下一个,repeat if equal
 
Attention
这里的 cx 的作用是确定一个最大比较位数 
每次比较,无论是否相等,si, di 都会变化,所以要注意边界 
 
 
2.3 repne cmpsb 
如果本次比较不相等则继续比较下一个,repeat if not equal
 
2.4 实现 strcmp 
strcmp      rep e   cmpsb 
     je   equal 
     dec   si 
     dec   di 
equal: 
如果最后一次比较相等,说明从 CX==0 处退出,两个字符串全等,di, si 正好停在字符串外面一位 
如果最后一次不相等,说明从 if (本次比较相等) 退出,不全等,di, si 停在第一个不同位置的后面一位 ,所以需要 dec 一次来找到第一个不相等的字符 
 
3 字符串扫描指令 
3.1 scasb 
将 al 与字符进行比较,scan string by byte
 
3.2 repne scasb 
如果本次比较不相等则继续比较下一个
 
3.2.1 应用:实现 strlen 
mov   ax ,   1000 h 
mov   es ,   ax 
mov   di ,   2000 h    ; es:di 就是目标字符串 
mov   cx ,   0 FFFFh    ; 最多查找 FFFF 次 
mov   al ,   0    ; 待查找的字符 
cld    ; 使用正方向 
rep ne   scasb 
not   cx    ; 相当于 FFFF-cx 
dec   cx 
由于扫描到 \0 时仍然会 cx--,所以 not cx 是包括 \0 的 
由于字符串长度不包括 \0,所以需要 dec 
 
3.3 repe scasb 
如果本次比较相等则继续比较下一个
 
3.3.1 应用:实现删除字符串前面的字符 
Question
加入 1000:0000 存有 ###ABC,要求跳过前面的 #,将剩余部分复制到 2000:0000
 
4 读取字符串指令 lodsb/w/d 
加载 ds:si 指向的内容并移动指针
 
4.1.1 rep lodsb 
实现用 CX 控制的读取给定长度内存
 
5 字符串写入指令 stosb/w/d 
5.1 stosb/w/d 填充指令 
进行一次填充,移动 di
 
5.1.1 rep stosb 
循环 cx 次 stosb
 
5.1.2 用处:内存初始化 
将 1000:10A0 开始共 100h 个字节都清零 mov   ax ,   1000 h 
mov   es ,   ax 
mov   di ,   10 A0h 
mov   cx ,   100 h 
cld 
xor   al ,   al 
rep   stosb 
或者使用 double word 填充,能够更快
将 1000:10A0 开始共 100h 个字节都清零 mov   ax ,   1000 h 
mov   es ,   ax 
mov   di ,   10 A0h 
mov   cx ,   40 h 
cld 
xor   eax ,   eax 
rep   stosd 
5.1.3 Example: 过滤字符 
ds:si -> "##AB#12#XY",es:di 指向空数组,cx=11 过滤字符串并放到空数组中
 
     cld 
again: 
     lodsb 
     cmp   al ,   ' #' 
     je   next 
     stosb 
next: 
     dec   cx 
     jnz   again