asm source code note 1.5_while循环的实现
发布日期:2021-06-30 22:05:59 浏览次数:2 分类:技术文章

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

查看Rlease版的do-while汇编实现

源代码

// test1020.cpp : Defines the entry point for the console application.//#include "stdafx.h"/// 求 1~N累加和size_t  add1toN(size_t nBegin, size_t nEnd);int _tmain(int argc, _TCHAR* argv[]){    size_t  nBegin  =   99;    size_t  nEnd    =   999 + 1;    _tprintf(L"add1toN(%d, %d) = %d\r\n", nBegin, nEnd, add1toN(nBegin, nEnd));    getwchar();    return 0;}size_t  add1toN(size_t nBegin, size_t nEnd){//     size_t  nIndex  =   0;//     size_t  nAddSum =   0;// //     for (nIndex = nBegin; nIndex <= nEnd; nIndex++)//         nAddSum += nIndex;/// 用do-while实现    size_t  nIndex  =   nBegin;    size_t  nAddSum =   0;    do     {        nAddSum += nIndex++;    } while (nIndex <= nEnd);    return nAddSum;}

OD 的汇编代码

00331000 >/$  B8 63000000   mov     eax, 63                          ;  累加数起始值为 0x6300331005  |.  33C9          xor     ecx, ecx                         ;  累加和为 ecx00331007  |>  03C8          /add     ecx, eax                        ; |累加eax到ecx00331009  |.  40            |inc     eax                             ; |被累加数eax++0033100A  |.  3D E8030000   |cmp     eax, 3E8                        ; |是否已经累加到了最后一个数 0x3e80033100F  |.^ 76 F6         \jbe     short 00331007                  ; |如果没有累加完, 继续00331011  |.  51            push    ecx                              ; |将参数压入, 调用wprintf00331012  |.  68 E8030000   push    3E8                              ; |<%d> = 3E8 (1000.)00331017  |.  6A 63         push    63                               ; |
= 63 (99.)00331019 |. 68 F4203300 push 003320F4 ; |format = "add1toN(%d, %d) = %d.."0033101E |. FF15 A4203300 call dword ptr [<&MSVCR90.wprintf>] ; \wprintf00331024 |. 83C4 10 add esp, 1000331027 |. FF15 9C203300 call dword ptr [<&MSVCR90.getwchar>] ; [getwchar0033102D |. 33C0 xor eax, eax0033102F \. C3 retn
可以看到 do-while实现很简洁, 没有使用 for循环那样的二分法累加, 逻辑简单, 代码实现短.

查看Rlease版的while汇编实现

源代码

// test1020.cpp : Defines the entry point for the console application.//#include "stdafx.h"/// 求 1~N累加和size_t  add1toN(size_t nBegin, size_t nEnd);int _tmain(int argc, _TCHAR* argv[]){    size_t  nBegin  =   99;    size_t  nEnd    =   999 + 1;    _tprintf(L"add1toN(%d, %d) = %d\r\n", nBegin, nEnd, add1toN(nBegin, nEnd));    getwchar();    return 0;}size_t  add1toN(size_t nBegin, size_t nEnd){//     size_t  nIndex  =   0;//     size_t  nAddSum =   0;// //     for (nIndex = nBegin; nIndex <= nEnd; nIndex++)//         nAddSum += nIndex;/// 用do-while实现//     size_t  nIndex  =   nBegin;//     size_t  nAddSum =   0;// //     do //     {//         nAddSum += nIndex++;//     } while (nIndex <= nEnd);    /// 用while实现    size_t  nIndex  =   nBegin;    size_t  nAddSum =   nIndex;    while (++nIndex <= nEnd)         nAddSum += nIndex;    return nAddSum;}
OD汇编代码

01391000 >/$  33D2          xor     edx, edx                         ;  edx 清零, 作为二分法累加的上半部分.01391002  |.  56            push    esi                              ;  保存现场, esi作为 add1toN的总累加和01391003  |.  33C9          xor     ecx, ecx                         ;  ecx作为二分法累加的下半部分的和01391005  |.  8D72 63       lea     esi, dword ptr [edx+63]          ;  第一个累加数为0x63, 直接放到总累加和中01391008  |.  B8 64000000   mov     eax, 64                          ;  第二个累加数为0x640139100D  |.  8D49 00       lea     ecx, dword ptr [ecx]             ;  对于本例没用, 可以优化掉01391010  |>  03D0          /add     edx, eax                        ;  累加上半部分01391012  |.  8D4C01 01     |lea     ecx, dword ptr [ecx+eax+1]      ;  累加下半部分01391016  |.  83C0 02       |add     eax, 2                          ;  值改变为下一个上半部分01391019  |.  3D E7030000   |cmp     eax, 3E7                        ;  如果没有到倒数第一个数, 继续累加0139101E  |.^ 76 F0         \jbe     short 0139101001391020  |.  3D E8030000   cmp     eax, 3E8                         ;  最后一个数是否被累加过了?01391025  |.  77 03         ja      short 0139102A01391027  |.  8D70 63       lea     esi, dword ptr [eax+63]          ;  如果最后一个数没有被累加过, 累加到总累加和中0139102A  |>  03CA          add     ecx, edx                         ; |总累加和加上上半部分和0139102C  |.  03F1          add     esi, ecx                         ; |总累加和加上下半部分和0139102E  |.  56            push    esi                              ; |压入参数, 调用wprintf0139102F  |.  68 E8030000   push    3E8                              ; |<%d> = 3E8 (1000.)01391034  |.  6A 63         push    63                               ; |
= 63 (99.)01391036 |. 68 F4203901 push 013920F4 ; |format = "add1toN(%d, %d) = %d.."0139103B |. FF15 A4203901 call dword ptr [<&MSVCR90.wprintf>] ; \wprintf01391041 |. 83C4 10 add esp, 1001391044 |. FF15 9C203901 call dword ptr [<&MSVCR90.getwchar>] ; [getwchar0139104A |. 33C0 xor eax, eax0139104C |. 5E pop esi0139104D \. C3 retn
可以看出 do-while循环的汇编实现清晰简练, 比 while, for 代码都简短.

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

上一篇:asm source code note 1.6_if else分支的实现
下一篇:asm source code note 1.4_do_while循环的实现

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月10日 04时40分24秒