注銷

          注銷

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            112 隨筆 :: 7 文章 :: 18 評(píng)論 :: 0 Trackbacks

          在傳統(tǒng)C中,函數(shù)的參數(shù)和返回值都是以復(fù)制傳送的.
          看這段代碼
          struct Big
          {
          ?char buf[1024];
          }B,B2;

          Big bigfun(Big b)
          {
          ?return b;
          }

          int main()
          {
          ?B2 = bigfun(B);
          ?return 0;
          }

          其中B2 = bigfun(B)要被由以下幾個(gè)過程組成
          1.B要以傳值方式傳送到函數(shù)的參數(shù)表中中
          2.如果返回值size很小,可以返回eax中
          ? 但是在這里,返回值size很大,要建立臨時(shí)變量
          ? 然后將臨時(shí)變量的地址入棧,此時(shí)非常象函數(shù)參數(shù)入棧
          ? 返回eax指向這個(gè)臨時(shí)變量
          3.將這個(gè)臨時(shí)變量拷貝到B2上

          B2 = bigfun(B);
          展開為
          ;構(gòu)造臨時(shí)堆棧
          004017AE? sub???????? esp,400h?;堆棧大小1024(400h)
          ;由于函數(shù)調(diào)用是傳值方式,所以將B復(fù)制到bigfun中的參數(shù)中
          ;相當(dāng)于將B push到堆棧中
          004017B4? mov???????? ecx,100h?;傳送大小1024(100h*4)
          004017B9? mov???????? esi,offset B (421138h) ;源是B首地址
          004017BE? mov???????? edi,esp?;目的為bigfun中的參數(shù)地址
          004017C0? rep movs??? dword ptr [edi],dword ptr [esi] ;復(fù)制
          ;調(diào)用函數(shù),此時(shí)push eax中的eax并非是函數(shù)參數(shù)壓棧,而是將一個(gè)臨時(shí)對(duì)象的指針壓棧
          004017C2? lea???????? eax,[ebp-4C4h]
          004017C8? push??????? eax?;將堆棧中一個(gè)臨時(shí)對(duì)象地址壓堆棧
          004017C9? call??????? bigfun (401750h) ;調(diào)用函數(shù)
          004017CE? add???????? esp,404h?;清除堆棧(400h+4),堆棧跳過函數(shù)參數(shù)表和函數(shù)返回地址
          ;臨時(shí)對(duì)象為返回變量,eax指向這個(gè)地址
          ;將這個(gè)臨時(shí)對(duì)象復(fù)制另一個(gè)臨時(shí)對(duì)象上
          004017D4? mov???????? ecx,100h?;傳送大小1024(100h*4)
          004017D9? mov???????? esi,eax?;目的上面臨時(shí)對(duì)象的地址
          004017DB? lea???????? edi,[ebp-8CCh] ;堆棧中第三個(gè)臨時(shí)對(duì)象
          004017E1? rep movs??? dword ptr [edi],dword ptr [esi] ;復(fù)制
          ;將第二個(gè)臨時(shí)對(duì)象復(fù)制到B2上
          004017E3? mov???????? ecx,100h?;傳送大小1024(100h*4)
          004017E8? lea???????? esi,[ebp-8CCh] ;堆棧中第三個(gè)臨時(shí)對(duì)象
          004017EE? mov???????? edi,offset B2 (421538h) ;目的為首地址
          004017F3? rep movs??? dword ptr [edi],dword ptr [esi] ;傳送


          Big bigfun(Big b) {
          展開為
          ;初始化堆棧,以ebp為基準(zhǔn),ebp+4指向?yàn)閞eturn address
          ;ebp+8為剛才壓入堆棧的上層函數(shù)中的臨時(shí)對(duì)象的地址
          ;ebp-4為臨時(shí)堆棧中第一個(gè)局部變量
          00401750? push??????? ebp?
          00401751? mov???????? ebp,esp?;ebp此時(shí)指向以前保存bp
          00401753? sub???????? esp,0C0h?;建立臨時(shí)堆棧,大小0C0h
          00401759? push??????? ebx?
          0040175A? push??????? esi?
          0040175B? push??????? edi
          ;初始化堆棧全部為0xcc
          0040175C? lea???????? edi,[ebp-0C0h]
          00401762? mov???????? ecx,30h
          00401767? mov???????? eax,0CCCCCCCCh
          0040176C? rep stos??? dword ptr [edi]
          ?return b;
          ;復(fù)制b到那個(gè)臨時(shí)對(duì)象上
          0040176E? mov???????? ecx,100h
          00401773? lea???????? esi,[b]
          00401776? mov???????? edi,dword ptr [ebp+8] ;ebp+8為參數(shù)表中的參數(shù)地址
          00401779? rep movs??? dword ptr [edi],dword ptr [esi]
          ;返回那個(gè)臨時(shí)變量的地址
          0040177B? mov???????? eax,dword ptr [ebp+8]
          }

          posted on 2006-11-19 10:13 注銷..... 閱讀(255) 評(píng)論(0)  編輯  收藏 所屬分類: c++
          主站蜘蛛池模板: 罗田县| 城市| 太保市| 杂多县| 耒阳市| 永兴县| 罗江县| 龙川县| 怀柔区| 柯坪县| 都江堰市| 萨嘎县| 永新县| 定远县| 景谷| 安化县| 唐山市| 浏阳市| 乌审旗| 白河县| 上栗县| 丹凤县| 邢台市| 施秉县| 武威市| 广灵县| 仙桃市| 平乐县| 崇阳县| 封开县| 新野县| 青川县| 武宣县| 广水市| 闽清县| 钟祥市| 社旗县| 阿拉善左旗| 漳州市| 定日县| 南康市|