留言簿

文章分类

文章档案

技术连接

最新评论

        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++