目录

052-纯汇编写字串比较函数strcmpA

053-STD和CLD,纯汇编写strcmpW

一、用纯汇编封装函数strcmpW

二、方向标志位(DF相关指令) STD/CLD


        尽管C库提供了strcmp,但了解其最高效的硬件实现是深入系统编程的关键。 本文将用纯汇编揭示这个经典函数背后的指令级优化。

052-纯汇编写字串比较函数strcmpA

知识点:

__declspec(naked)   纯汇编

堆栈平衡

参数传递

用纯汇编封装函数strcmpA 

__declspec(nakedint strcmpA(char* s1,char *s2)// scasw strcmpW

{

       __asm

       {  

              push ebp         // esp+4+4 s1 //esp+4+8

              mov ebp,esp         //构建栈底

              //mov al,0

              xor al,al        //eax=0

              mov edi,[ebp+4+4]

              mov ecx,-1         //0xFFFF FFFF

              repnz scasb;

              not ecx         // '\0' 计算s1字串长度,指定repz循环次数

              mov edi,[ebp+4+4]

              mov esi,[ebp+4+8]

              repz cmpsb         // edi,esi

              //[edi-1] [esi-1]

              xor eax,eax

              xor edx,edx

              mov al,[edi-1]

              mov dl,[esi-1]

              sub eax,edx         //相等eax=0,大于返回结果>0 小于<0

              pop ebp //栈平衡

              retn

       }

}

#include "stdafx.h"

int strcmpA(char* s1,char *s2)

{

       int i=0,j=0;

       __asm

       {  

              xor al,al ;        //eax=0

              mov edi,s1;

              mov ecx,-1;

              cld;        //DF标志位 0

              repnz scasb;

              not ecx;

              mov i,ecx;     //is1的长度

             

              mov edi,s2;

              mov ecx,-1;

              repnz scasb;

              not ecx;

              mov j,ecx;     //js2的长度

              cmp ecx,i;    //如果s1s2长度不一样,则跳转到end

              jnz end;

              mov edi,s1;

              mov esi,s2;

              repz cmpsb   //如果直到ECX==0才结束,就表示字符串相同

              cmp ecx,0;

              jnz end;

              mov eax,1;

              jmp over;             

end:

              mov eax,0;

over:

       }

}

int _tmain(int argc, _TCHAR* argv[])

{

       int i=0;

       char *s1="abcde21";

       char *s2="abcde21";

       i=strcmpA(s1,s2);

       printf("%d",i);

       return 0;

}

053-STDCLD,纯汇编写strcmpW

知识点:

__declspec(naked)   纯汇编

堆栈平衡

参数传递

用纯汇编封装函数strcmpW

STDCLD指令

 

一、用纯汇编封装函数strcmpW

 1、用repnz scasw计算字串长度

 2、用repz cmpsw比较字串

 3、把比较的结果存放在EAX里边返回

__declspec(nakedint strcmpw(WCHAR* s1,WCHAR *s2)// scasw strcmpW

{

       __asm

       {  

              push ebp

         mov ebp,esp

        // esp+4+4  s1 //esp+4+8 s2

              xor ax,ax        //edi所在地址查找字节的

              mov edi,[ebp+4+4]

              mov ecx,-1         //0xFFFF FFFF

              repnz scasw;

              not ecx         // '\0' 计算s1字串长度,指定repz循环次数

              mov edi,[ebp+4+4]

              mov esi,[ebp+4+8]

              repz cmpsw         // 每次比较2字节 (1个字)

              xor eax,eax

              xor edx,edx

              mov ax,[edi-2]

              mov dx,[esi-2]

              sub eax,edx         //相等eax=0,大于返回结果>0 小于<0

              pop ebp

              retn

       }

二、方向标志位(DF相关指令) STD/CLD

    STD   => DF=1

    CLD   => DF=0

读取UNICODE字符串(宽字符):%ws

读取ASCII字符串:%s

#include "stdafx.h"

int strcmpA(wchar_t* s1,wchar_t *s2)

{

       int i=0,j=0;

       __asm

       {  

              xor ax,ax;

              mov edi,s1;

              mov ecx,-1;

              cld;        //DF标志位 0

             repnz scasw;

              not ecx;

              mov i,ecx;     //is1的长度

             

              mov edi,s2;

              mov ecx,-1;

              repnz scasw;

              not ecx;

              mov j,ecx;     //js2的长度

              cmp ecx,i;     //如果s1s2长度不一样,则跳转到end

              jnz end;

              mov edi,s1;

              mov esi,s2;

              repz cmpsw          //如果直到ECX==0才结束,就表示字符串相同

              cmp ecx,0;

              jnz end;

              mov eax,1;

              jmp over;             

end:

              mov eax,0;

over:

       }

}

int _tmain(int argc, _TCHAR* argv[])

{

       int i=0;

       wchar_t *s1=L"ABCD";  

       wchar_t *s2=L"ABCD";

       i=strcmpA(s1,s2);

       printf("%d",i);

       return 0;

}


计算机科学与技术 & 计算机网络技术:双专业课程体系完全导航指南

 本系列目录

1、逆向工程基础:Ollydbg(OD)调试器实战与MOV指令寻址方式精讲

2、汇编语言核心概念精讲:从ADD、SUB、MOVSX/MOVZX到LEA与寄存器详解

3、x86汇编条件跳转指令完全解析:从CMP到有/无符号跳转与If实现

4、x86汇编函数调用完全解析:栈帧(EBP/ESP)构建与三种调用约定(cdecl/stdcall/fastcall)对比

5、汇编逆向还原核心:if-else与switch-case结构的识别与C代码重构

6、编译器优化揭秘:对比for循环的汇编实现与INC vs ADD指令的性能抉择

7、x86浮点运算基础:FPU寄存器、FLD/FSTP与FADD/FSUB等指令精讲

8、汇编位移指令全解与逆向实战:从SHR/SHL到ROL/ROR,逆向分析strcmp

9、汇编位运算指令精讲:掌握AND/OR/XOR/NOT四大核心操作

10、x86汇编字符串处理:SCASB/SCASW指令与REPNE/REPE重复前缀详解

11、汇编实战:用REPNZ SCASB与REPZ CMPSB从零实现strcmpA/W

12、x86汇编批量操作指令:LOOP循环控制与STOS/LODS串操作详解

13、x86条件置位指令(SETxx)完全指南:从标志位解读到条件判断实战

14、游戏逆向工程实战:从CALL分析、基址定位到冷却破解与内存修改

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐