Visual Studio开发工具为我们提供了运行库的源代码,这些源代码是非常有价值的学习资源,从今天起我会陆续分析这些源代码,希望对一些朋友代码帮助,同时也能提高自己。分析的所有源代码是vs 2003附带的。vs 2003附带的源代码在vs2003的安装目录的\Vc7\crt\src下.对于一些比较复杂的代码我会仔细分析,对于比较简单的代码,我只是把他的注释翻译一下,或者小小的改变一下贴出来.
今天分析的文件是intel下的_memicmp.asm,该代码主要 用于优化memicmp这个函数,该函数用于比较两个字符串,但是忽略大小写。
同功能的C代码如下:
1 /*++
2 目的:
3 比较count个字节的内存块,保存在first和last中.
4 比较时字符转换为小写字符(不改变原字符)
5
6 参数:
7 char *first - 比较的内存块
8 char *last - 比较的内存块
9 unsigned count - 比较的字节数
10
11 返回值:
12 如果first < last, 返回值 < 0
13 如果first == last, 返回值 = 0
14 如果first > last, 返回值 > 0
15 --*/
16 int memicmp (char * first, char * last, unsigned count)
17 {
18 if (!count)
19 {
20 return(0);
21 }
22
23 while (--count && tolower(*first) == tolower(*last))
24 {
25 first++;
26 last++;
27 }
28
29 return(tolower(*first) - tolower(*last));
30 }
优化的汇编代码如下:
1
2 memicmp proc \
3 uses edi esi ebx, \
4 first:ptr byte, \
5 last:ptr byte, \
6 count:IWORD
7
8 ; 判断count
9 mov ecx,[count] ; cx = count
10 or ecx,ecx
11 jz short toend ; 如果 count=0, 什么都不做
12
13 mov esi,[first] ; si = first
14 mov edi,[last] ; di = last
15
16 mov bh,'A' ; 大写字母开始
17 mov bl,'Z' ; 大写字母结束
18 mov dh,'a'-'A' ; 大写字母转换成小写字母的常数
19
20 align 4
21
22 lupe:
23 mov ah,[esi] ; ah = *first
24 add esi,1 ; first++
25 mov al,[edi] ; al = *last
26 add edi,1 ; last++
27
28 cmp ah,al ; 转换前比较是否相等
29 je short dolupe
30
31 cmp ah,bh ; ah < 'A' ??
32 jb short skip1
33
34 cmp ah,bl ; ah > 'Z' ??
35 ja short skip1
36
37 add ah,dh ; 转换成小写
38
39 skip1:
40 cmp al,bh ; al < 'A' ??
41 jb short skip2
42
43 cmp al,bl ; al > 'Z' ??
44 ja short skip2
45
46 add al,dh ; 转换成小写
47
48 skip2:
49 cmp ah,al ; *first == *last ??
50 jne short differ ; nope, 不匹配
51
52 dolupe:
53 sub ecx,1
54 jnz short lupe
55
56 jmp short toend ; ecx = 0, 返回 0
57
58 differ:
59 mov ecx, -1 ; 先假设last是较大的字符串
60 jb short toend ; 如果真的是last大,那么返回-1
61 neg ecx ; 如果是first大,则对ecx取反,返回1
62
63 toend:
64 mov eax,ecx ; eax保存返回值
65
66 ret ; C语言调用约定(_cdecl)的返回
67
68 memicmp endp
posted on 2009-07-13 03:05
贝乐 阅读(99)
评论(0) 编辑 收藏 引用 所属分类:
C/C++