函数实现:


[cpp] 
1. /***********************************************************************/
2. /*             比较两个字符串是否相等                                  */
3. /**********************************************************************/
4. bool isEqual(const char * str1,const char
5. {  
6.   
7. //  if (strlen(str1)!=strlen(str2)){//长度不相等则不相等
8. //      return false;
9. //  }
10.   
11. //对上面判断语句的汇编实现
12.     __asm  
13.     {  
14. //str1地址入栈
15. //调用c函数获取长度
16. //堆栈平衡[c调用约定"__cdecl"规定由函数的调用者释放堆栈]
17. //存放比较结果,为了避免后面再次调用strlen函数引起返回值覆盖[函数的返回值规范约定保存在eax里面]
18. //str2地址入栈
19. //调用c函数获取长度[函数的返回值规范约定保存在eax里面]
20. //堆栈平衡[c调用约定"__cdecl"规定由函数的调用者释放堆栈]
21. //比较两个字符串的长度
22. //不相等则跳转到 exit2
23.     }  
24.   
25. //  for (;str1<str1+strlen(str1);str1++,str2++)//循环比较每个字符是否相等,如果某个字符不相等那么整个也不相等
26. //  {
27. //      if (*str1!=*str2){
28. //          return false;
29. //      }
30. //  }
31.   
32. //对上面for循环的汇编实现
33.     __asm  
34.     {  
35.   
36. //str1地址入栈
37. //调用c函数获取长度
38. //堆栈平衡[c调用约定"__cdecl"规定由函数的调用者释放堆栈]
39. //取str1地址到esi寄存器
40. //复制到edx寄存器
41. //取str2地址到edi寄存器
42. char      //计算指针偏移量[eax中存放的是strlen的返回值,str1是字符指针,对指针做算术运算时参与运算的值是它所指向的类型的长度]
43. //计算循环上限[str1+strlen(str1)]
44. beginfor:  
45. //比较[str1<str1+strlen(str1)]
46. //如果不小于那么结束循环[当然也可以用"大于等于"跳转指令]
47. //取str1的一个字符到bl寄存器
48. //取str2的一个字符到cl寄存器
49. //比较两个字符大小
50. //不相等则结束
51. char       //str1指针向前移动
52. char       //str2指针向前移动
53. //跳转到beginfor继续循环
54. endfor:  
55.           
56.     }  
57.   
58.     __asm  
59.     {  
60.   
61. exit1:  
62. //返回相等[return true]
63. //结束
64. exit2:  
65. //返回不相等[return false]       
66. exit:                           //程序结束
67.     }  
68.   
69. }


 

测试:


[cpp] 
1. #include "stdafx.h"
2. #include "string.h"
3. bool isEqual(const char * ,const char
4. extern "C" void _stdcall startWith(const char *,const char *,bool
5. extern "C" int __stdcall ncompare(int,int);  
6. int main(int argc, char* argv[])  
7. {  
8.     __asm  
9.     {  
10.         mov eax,eax  
11.         mov eax,eax  
12.     }  
13. char * course1 = "java5";  
14. char * course2 = "java6";  
15. char * msg1 = "不相等";  
16. char * msg2 = "相等";  
17.   
18. //  if (::strcmp(course1,course2))
19. //  {
20. //      
21. //      printf("不相等");
22. //  }
23. //  else
24. //  {
25. //      printf("相等");
26. //  }
27.       
28. //  bool ret = isEqual(course1,course2);
29. //  if (ret)
30. //  {
31. //      printf("相等");
32. //  }
33. //  else
34. //  {
35. //      printf("不相等");
36. //  }
37.       
38. //调用自定义的函数
39.     __asm  
40.     {  
41. //传递第2个参数
42. //传递第1个参数
43. //调用函数[VC编译器默认采用c调用约定"__cdecl"]
44. //堆栈平衡[c调用约定"__cdecl"规定由函数的调用者释放堆栈]
45. //eax是上面函数调用的返回值,对eax本身进行与操作[只影响标志位,不影响寄存器本身],检查其值是否为
46.   
47. 0  
48. //je等同于jz,如果eax的值是0[说明返回的是false],那么与结果值为0,则zf=1,则函数调用的
49.   
50. 返回的值是false[不相等]  
51. //相等,msg2地址入栈[向printf传递参数]
52. //调用c函数prinf输出
53. //堆栈平衡
54. //程序结束
55. local1:  
56. //不相等,msg1地址入栈[向printf传递参数]
57. //调用c函数prinf输出
58. //堆栈平衡
59. local2:  
60.     }  
61.       
62.   
63.   
64.   
65. return
66. }


 


测试字符串是否以某个子字符串开始

函数:


[cpp] 
1. /************************************************************************/
2. /*检查是否以prefix开始                                                 */
3. /*  content:整个字符串                                                   
4. 
5. */
6. /*  prefix: 要查找的字符串                                             */
7. /*  result: 返回的值                                                    */
8. /************************************************************************/
9. void _stdcall startWith(const char * pContent,const char * pPrefix,bool
10. {  
11. //  if (pContent==NULL || pPrefix == NULL || strlen(pContent)<strlen(pPrefix))
12. //  {
13. //      *pResult = false;
14. //      return;
15. //  }
16.   
17. /**
18.     当前堆栈情况
19.     0x12FEEC:   0012FF80    //进入当前方法前的EBP的值
20.         +0x4    0040D9CC    //当前方法的返回地址
21.         +0x8    0012FF70    //传递给当前方法的第一个参数PContent
22.         +0xc    0012FF68    //传递给当前方法的第二个参数pPrefix
23.         +0x10   0012FF50    //传递给当前方法的第三个参数pResult
24.     */
25.       
26. //验证执行条件
27.     __asm  
28.     {  
29. //验证pContent
30. //为0则退出
31. //验证pPrefix
32. //为0则退出
33.           
34. //strlen(pContent)-->ebx
35.         call strlen;          
36.         add esp,4  
37.         mov ebx,eax  
38.   
39. //strlen(pPrefix)-->eax
40.         call strlen  
41.         add esp,4  
42.   
43. //strlen(pContent)<strlen(pPrefix)
44.         jl exitwithfalse  
45.     }  
46.   
47. const char
48. const char
49.   
50. //  for (; pp<pPrefix+(strlen(pPrefix)*sizeof(char)); pp++,pc++)
51. //  {
52. //      if (*pp!=*pc)
53. //      {
54. //          *pResult = false;
55. //          return;
56. //      }
57. //  }
58. //以下是循环的代码实现
59.     __asm  
60.     {  
61. //strlen(pPrefix)
62.         call strlen  
63. //
64. char      //strlen(pPrefix)*sizeof(char)
65.         mov edi,pPrefix           
66. //pPrefix+strlen(pPrefix)*sizeof(char)
67. beginfor:  
68. //if (pp<pPrefix+strlen(pPrefix)*sizeof(char))
69. //不满足循环条件则退出循环
70.           
71.         mov eax,pp  
72. //*pp-->al
73.         mov ebx,pc  
74. //*pc-->bl
75. //if (*pp!=*pc)
76. //发现不通的字符则退出循环
77. char        //pp++
78. char        //pc++
79. //继续下一轮循环
80.     }  
81.   
82. //*pResult =true;
83.     __asm   
84.     {  
85.         endfor:  
86.             jmp exitwithtrue  
87.     }  
88.       
89.     __asm  
90.     {  
91. exitwithfalse:  
92.         mov eax,[ebp+0x10]  
93. //*pResult=0
94.         jmp exit  
95. exitwithtrue:  
96.         mov eax,[ebp+0x10]  
97. //*pResult=1
98. exit:           //退出
99.     }  
100. }


 

测试代码:


[cpp] 
1. int main(int argc, char* argv[])  
2. {  
3.   
4. char content[] = "welcome to you";  
5. char prefix[] ="welcome";  
6. char msg1[] = "包含";  
7. char msg2[] = "不包含";  
8. char fmt[] = "%s/n";  
9.   
10. bool result = false;  
11. bool
12.       
13. // startWith(content,prefix,&result);
14. // printf("%s/n",result?"包含":"不包含");
15.   
16. //以下是汇编实现版本
17.     __asm  
18.     {  
19. //传递第三个参数
20. //传递第二个参数--取数组首地址
21. //传递第二个参数
22. //传递第一个参数--取数组首地址
23. //传递第一个参数
24. //调用函数[该函数采用__stdcall约定,将由北调用函数自身负责堆栈的平衡]
25.           
26. //比较结果是否为1[true]
27. //如果为1说明包含,跳转到processeq处理显示包含信息
28. //否则说明不包含--取msg2数组首地址
29. //否则说明不包含--传递第二个参数
30. //传递第一个参数--取数组fmt首地址
31. //传递第一个参数
32. //调用函数输出信息
33. //堆栈平衡
34. //程序结束
35. processeq:                  //处理包含的情况
36. //取数组msg1的首地址
37. //第二个参数入栈
38. //去数组fmt的首地址
39. //第一个参数入栈
40. //调用函数输出信息
41. //堆栈平衡
42. exit:                       //程序结束
43.     }  
44.   
45. return
46. }