还原自己写的冒泡排序
发布日期:2021-06-30 22:10:23 浏览次数:2 分类:技术文章

本文共 8261 字,大约阅读时间需要 27 分钟。

试验

自己的源码

// hw.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include 
#include
#include
#include
#include
#define ARY_SIZE 9void fnSortBubble(int* pAry, int nLenAry) { int i = 0; int j = 0; int iTmp = 0; for (i = 0; i < (nLenAry - 1); i++) { for (j = 0; j < (nLenAry - 1 - i); j++) { if (pAry[j] > pAry[j + 1]) { iTmp = pAry[j]; pAry[j] = pAry[j + 1]; pAry[j + 1] = iTmp; } } }}int main(int argc, char* argv[]){ int i = 0; int iAry[ARY_SIZE]; int iLenAry = sizeof(iAry) / sizeof(iAry[0]); for (i = 0; i < iLenAry; i++) { iAry[i] = rand(); } fnSortBubble(iAry, iLenAry); for (i = 0; i < iLenAry; i++) { printf("iAry[%-2d] = %d\r\n", i, iAry[i]); } /** run result iAry[0 ] = 41 iAry[1 ] = 6334 iAry[2 ] = 11478 iAry[3 ] = 15724 iAry[4 ] = 18467 iAry[5 ] = 19169 iAry[6 ] = 26500 iAry[7 ] = 26962 iAry[8 ] = 29358 请按任意键继续. . . */ system("pause"); return 0;}

IDA笔记

.text:00401000 ; =============== S U B R O U T I N E =======================================.text:00401000.text:00401000.text:00401000 ; int __cdecl fnSort(int iAryAddr, int iAryElementCnt).text:00401000 fnSort          proc near               ; CODE XREF: _main+22p.text:00401000.text:00401000 iAryAddr        = dword ptr  4.text:00401000 iAryElementCnt  = dword ptr  8.text:00401000.text:00401000 iLoopCnt = eax.text:00401000                 mov     iLoopCnt, [esp+iAryElementCnt].text:00401004                 dec     iLoopCnt        ; eax = 元素个数 - 1.text:00401005                 test    iLoopCnt, iLoopCnt.text:00401007                 jle     short L_END_SORT ; 一个元素不用排序.text:00401009                 push    ebx.text:0040100A 精干的算法,寄存器变量的使用是非常简洁的.text:0040100A                 mov     ebx, [esp+4+iAryAddr].text:0040100E                 push    ebp.text:0040100F                 push    esi.text:00401010 iLoopCntForLoop1 = edi.text:00401010                 push    iLoopCntForLoop1 ; save.text:00401011                 mov     iLoopCntForLoop1, iLoopCnt.text:00401013 _iLoopCnt = ebp.text:00401013                 mov     _iLoopCnt, iLoopCnt.text:00401015.text:00401015 L_LOOP1:                                ; CODE XREF: fnSort+33j.text:00401015 pAry = ebx.text:00401015                 test    iLoopCntForLoop1, iLoopCntForLoop1.text:00401017                 jle     short L_LOOP1_NEXT.text:00401019 pAryCur = eax.text:00401019                 mov     pAryCur, pAry.text:0040101B iLoopCntForLoop2 = esi.text:0040101B                 mov     iLoopCntForLoop2, iLoopCntForLoop1.text:0040101D.text:0040101D L_LOOP2:                                ; CODE XREF: fnSort+2Fj.text:0040101D                 mov     ecx, [pAryCur]  ; 临时寄存器变量搞了2个: ecx, edx.text:0040101F                 mov     edx, [pAryCur+4].text:00401022                 cmp     ecx, edx.text:00401024                 jle     short L_NOT_NEED_SORT ; i++.text:00401026                 mov     [pAryCur], edx  ; if (pAry[i + 0] > pAry[i + 1]) { 交换数据 }.text:00401028                 mov     [pAryCur+4], ecx.text:0040102B.text:0040102B L_NOT_NEED_SORT:                        ; CODE XREF: fnSort+24j.text:0040102B                 add     pAryCur, 4      ; i++.text:0040102E                 dec     iLoopCntForLoop2.text:0040102F                 jnz     short L_LOOP2   ; 临时寄存器变量搞了2个: ecx, edx.text:00401031.text:00401031 L_LOOP1_NEXT:                           ; CODE XREF: fnSort+17j.text:00401031                 dec     iLoopCntForLoop1.text:00401032                 dec     _iLoopCnt.text:00401033                 jnz     short L_LOOP1.text:00401035                 pop     edi             ; restore.text:00401036                 pop     esi.text:00401037                 pop     ebp.text:00401038                 pop     ebx.text:00401039.text:00401039 L_END_SORT:                             ; CODE XREF: fnSort+7j.text:00401039                 retn.text:00401039 fnSort          endp.text:00401039.text:00401039 ; ---------------------------------------------------------------------------.text:0040103A                 align 10h.text:00401040.text:00401040 ; =============== S U B R O U T I N E =======================================.text:00401040.text:00401040.text:00401040 ; int __cdecl main(int argc, const char **argv, const char **envp).text:00401040 _main           proc near               ; CODE XREF: start+AFp.text:00401040.text:00401040 iAry_9          = byte ptr -24h.text:00401040 argc            = dword ptr  4.text:00401040 argv            = dword ptr  8.text:00401040 envp            = dword ptr  0Ch.text:00401040.text:00401040                 sub     esp, 24h.text:00401043                 push    esi.text:00401044                 push    edi.text:00401045 pAry = esi.text:00401045                 lea     pAry, [esp+2Ch+iAry_9] ; 数组首地址.text:00401049                 mov     edi, 9          ; 数组元素个数 = 9.text:0040104E.text:0040104E L_INIT_ARY:                             ; CODE XREF: _main+19j.text:0040104E                 call    _rand.text:00401053                 mov     [pAry], eax.text:00401055                 add     pAry, 4.text:00401058                 dec     edi.text:00401059                 jnz     short L_INIT_ARY ; 数组初始化.text:00401059                                         ; ;.text:0040105B                 lea     eax, [esp+2Ch+iAry_9].text:0040105F                 push    9               ; iAryElementCnt.text:00401061                 push    eax             ; iAryAddr.text:00401062                 call    fnSort          ; 排序.text:00401067                 add     esp, 8.text:0040106A                 xor     esi, esi.text:0040106C                 lea     edi, [esp+2Ch+iAry_9] ; 数组首地址.text:00401070.text:00401070 L_LOOP_PRINT_ARY:                       ; CODE XREF: _main+48j.text:00401070                 mov     ecx, [edi].text:00401072                 push    ecx.text:00401073                 push    esi.text:00401074                 push    offset Format   ; "iAry[%-2d] = %d\r\n".text:00401079                 call    _printf.text:0040107E                 add     esp, 0Ch.text:00401081                 inc     esi.text:00401082                 add     edi, 4.text:00401085                 cmp     esi, 9.text:00401088                 jl      short L_LOOP_PRINT_ARY ; 循环打印数组.text:00401088                                         ; ;.text:0040108A                 push    offset aPause   ; "pause".text:0040108F                 call    _my_system.text:00401094                 add     esp, 4.text:00401097                 xor     eax, eax.text:00401099                 pop     edi.text:0040109A                 pop     esi.text:0040109B                 add     esp, 24h.text:0040109E                 retn.text:0040109E _main           endp.text:0040109E.text:0040109E ; ---------------------------------------------------------------------------

还原后的代码

// hw.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include 
#include
int __cdecl fnSort(int iAryAddr, int iAryElementCnt) { int iLoopCnt = iAryElementCnt; int iLoopCntCpy = iLoopCnt; int* pAry = (int*)iAryAddr; int* pAryCur = NULL; int iTmp = 0; if (--iLoopCnt <= 0) { return 0; // 一个元素不用排序 } // 最大的数经过一轮后,换到最后面去了. while (iLoopCnt > 0) { pAryCur = pAry; iLoopCntCpy = iLoopCnt; do { if (*pAryCur > *(pAryCur + 1)) { iTmp = *pAryCur; *pAryCur = *(pAryCur + 1); *(pAryCur + 1) = iTmp; } pAryCur++; } while (--iLoopCntCpy != 0); if (0 == --iLoopCnt) { break; } } return 0;}int main(int argc, char* argv[]){ int iAry_9[9]; int i = 0; // L_INIT_ARY for (i = 0; i < 9; i++) { iAry_9[i] = rand(); } fnSort((int)&iAry_9[0], 9); // L_LOOP_PRINT_ARY for (i = 0; i < 9; i++) { printf("iAry[%-2d] = %d\r\n", i, iAry_9[i]); } system("pause"); return 0;}

总结

编译器做的优化挺有意思,交换2个变量时,用了2个寄存器保存src和dst.而不是搞一个中间变量.

暂时只能做到等价还原, 在C语言层面,无法还原出原来的for循环,只能做成do-while或while。

转载地址:https://lostspeed.blog.csdn.net/article/details/52506911 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:strcpy的内联实现
下一篇:查看google快照

发表评论

最新留言

很好
[***.229.124.182]2024年04月06日 14时28分16秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章