青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

沒畫完的畫

喂馬 劈柴 BBQ~
posts - 37, comments - 55, trackbacks - 0, articles - 0
  C++博客 ::  :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
注: 本文摘自互聯(lián)網(wǎng),本人看了按理解加了些東西

為了弄清楚函數(shù)的堆棧,Google了一下,找到下面代碼作為實(shí)驗(yàn)
 1#include <stdio.h>
 2#include <string.h>
 3
 4void func1(int input1, int input2)
 5{
 6    int j;
 7    char c;
 8    short k;
 9
10    j = 0;
11    c = 'a';
12    k = 1;
13
14    printf("sum=%d\n", input1+input2);
15
16    return;
17}

18
19int main()
20{
21    char output[8= "abcdef";
22    int i, j;
23
24    i=2;
25    j=3;
26    func1(i,j);
27
28    printf("%s\r\n", output);
29
30    return 0;
31}

32


本人在 vc6 + winxp 進(jìn)行調(diào)試
vc6 中在 fun1 設(shè)置斷點(diǎn),按F5,  到達(dá)斷點(diǎn)后,選擇菜單 view -> Disassembly 就可以看到代碼對應(yīng)的匯編語句

調(diào)用 func1() 之前

26:       func1(i,j);
004010D7   mov         ecx,dword ptr [ebp-10h]
004010DA   push        ecx
004010DB   mov         edx,dword ptr [ebp-0Ch]
004010DE   push        edx
004010DF   call        @ILT+0(func1) (00401005)
004010E4   add         esp,8
------------------------------------------------
EAX = 00000000 EBX = 7FFDE000 ECX = 00006665 EDX = 00370E00
ESI = 00000000 EDI = 0012FF80
EIP = 004010D7 ESP = 0012FF24 EBP = 0012FF80 EFL = 00000246
------------------------------------------------
i,j 分別存放在棧中,地址分別是
------------------------------------------------
ebp-10h = 0x0012FF80h - 0x10h = 0x0012FF70h
ebp-0Ch = 0x0012FF80h - 0x0Ch = 0x0012FF74h

0012FF70  03 00 00 00 02 00 00  .......
0012FF77  00 61 62 63 64 65 66  .abcdef

0012FF6D  CC CC CC 03 00 00 00  燙.....
0012FF74  02 00 00 00 61 62 63  ....abc

從內(nèi)存存放的內(nèi)容可知, i, j 分別存放于 0x0012FF70H, 0x0012FF74H
分別占了四個字節(jié)

在調(diào)用 func1() 之前, 先將 i, j 壓入堆棧, 壓入堆棧的順序是 i, j
(故出棧的順序是j, i, 請記住, 這里的 傳遞函數(shù)參數(shù) 默認(rèn)是 __cdecl) 

接著調(diào)用了 call 指令
執(zhí)行 call 指令之前的寄存器狀態(tài)
------------------------------------------------
EAX = 00000000 EBX = 7FFDE000 ECX = 00000003 EDX = 00000002
ESI = 00000000 EDI = 0012FF80
EIP = 004010DF ESP = 0012FF1C EBP = 0012FF80 EFL = 00000246
------------------------------------------------
執(zhí)行 call 指令之后的寄存器狀態(tài)
EAX = 00000000 EBX = 7FFDE000 ECX = 00000003 EDX = 00000002
ESI = 00000000 EDI = 0012FF80
EIP = 00401005 ESP = 0012FF18 EBP = 0012FF80 EFL = 00000246
------------------------------------------------
變化的是 EIP 與 ESP
棧頂指針寄存器ESP:保存棧頂?shù)刂?指針)
此時 ESP 向低地址偏移了四個字節(jié)
可見 call 指令執(zhí)行了一個 push 操作

查看 ESP 對象的地址 0x0012FF18 的內(nèi)容
0012FF18  E4 10 40 00 02 00 00  ..@....
0012FF1F  00 03 00 00 00 00 00  .......

push 進(jìn)去的數(shù)是 0x004010E4, 再看回調(diào)用 call 之后的代碼

26:       func1(i,j);
004010D7   mov         ecx,dword ptr [ebp-10h]
004010DA   push        ecx
004010DB   mov         edx,dword ptr [ebp-0Ch]
004010DE   push        edx
004010DF   call        @ILT+0(func1) (00401005)
004010E4   add         esp,8

push 進(jìn)去的數(shù)剛好是 call 指令后面的指令地址 0x004010E4  

為什么沒有看到push指令呢?
原來在CALL操作中,隱式地把call指令后續(xù)第一條指令的地址0x004010E4 入棧,
然后再無條件地跳轉(zhuǎn)到func1()函數(shù)繼續(xù)執(zhí)行。

@ILT+0(?func1@@YAXHH@Z):
00401005   jmp         func1 (00401020)

004010DF   call        @ILT+0(func1) (00401005)

奇怪的事情是 call 后面的操作數(shù)應(yīng)該是 func1 的地址 0x00401020 才對, 為何是 0x00401005?
還是一個 @ILT+0 的東東是什么?

在DEBUG版本中,VC匯編程序會產(chǎn)生一個函數(shù)跳轉(zhuǎn)指令表,
該表的每個表項存放一個函數(shù)的跳轉(zhuǎn)指令。
程序中的函數(shù)調(diào)用就是利用這個表來實(shí)現(xiàn)跳轉(zhuǎn)到相應(yīng)函數(shù)的入口地址。

ILT就是函數(shù)跳轉(zhuǎn)指令表的名稱,是Import Lookup Table的縮寫;
@ILT就是函數(shù)跳轉(zhuǎn)指令表的首地址。
在DEBUG版本中增加函數(shù)跳轉(zhuǎn)指令表,其目的是加快編譯速度,當(dāng)某函數(shù)的地址發(fā)生變化時,只需要修改ILT相應(yīng)表項即可,而不需要修改該函數(shù)的每一處引用。
注意:在RELEASE版本中,不會生成ILT,也就是說call指令的操作數(shù)直接是函數(shù)的入口地址,例如在本例中是這樣的:call 00401020


接下來, 應(yīng)該看一下 jmp func1 后, 做了哪些東西

4:    void func1(int input1, int input2)
5:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,4Ch
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-4Ch]
0040102C   mov         ecx,13h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
------------------------------------------------
此時各寄存器的值為
EAX = 00000000 EBX = 7FFDE000 ECX = 00000003 EDX = 00000002
ESI = 00000000 EDI = 0012FF80
EIP = 00401020 ESP = 0012FF18 EBP = 0012FF80 EFL = 00000246

ebp 為 main 函數(shù)層的 棧內(nèi)存基地址
esp 為 當(dāng)前的棧頂?shù)刂?/p>

00401020   push        ebp
00401021   mov         ebp,esp

這兩個語句 先把 ebp 壓入堆棧, 再把 esp 賦值給 ebp
這兩句的作用將在后面說明

00401023   sub         esp,4Ch
然后,棧頂指針esp向低地址偏移76(0x4C)字節(jié)。這里相當(dāng)于為func1()函數(shù)層分配了棧內(nèi)存。
(為什么偏偏是 76 是字節(jié)?)
(題外話: 平時程序調(diào)試的 stack over 又是如何造成的?)

接著又把 ebx, esi, edi 分別入棧, 目的是為了保存 main 函數(shù)層的相關(guān)內(nèi)容
00401026   push        ebx
00401027   push        esi
00401028   push        edi

最后用0xCC初始化上述為func1()函數(shù)層所分配的棧內(nèi)存的每個字節(jié)。這里每一步用F11單步跟蹤,棧內(nèi)存的變化你會看得更清楚。
00401029   lea         edi,[ebp-4Ch]     ; 將有效的地址 [ebp-0x4Ch] 賦值到 edi
0040102C   mov         ecx,13h           ;
00401031   mov         eax,0CCCCCCCCh    ;
00401036   rep stos    dword ptr [edi]   ;

stos指令:
字符串存儲指令 STOS
格式: STOS OPRD
其中OPRD為目的串符號地址.
功能: 把AL(字節(jié))或AX(字)中的數(shù)據(jù)存儲到DI為目的串地址指針?biāo)鶎ぶ返拇鎯ζ鲉卧腥?指針DI將根據(jù)DF的值進(jìn)行自動調(diào)整.
由于上面的指令是 dword ptr 類型
dword 表示雙字 ptr 表示取首地址
那么 stos    dword ptr [edi] 執(zhí)行的操作就是
將 ES:[DI]←AX,DI←DI±4   (DI 加或減是由 DF 標(biāo)志位確定的)
如果是 那么 stos word ptr [edi] 的話那么就是
將 ES:[DI]←AL,DI←DI±2   (DI 加或減是由 DF 標(biāo)志位確定的)
不然推出 stos BYTE ptr [edi]

注:
DF:方向標(biāo)志DF位用來決定在串操作指令執(zhí)行時有關(guān)指針寄存器發(fā)生調(diào)整的方向。

重復(fù)前綴
格式: REP           ;CX<>0 重復(fù)執(zhí)行字符串指令

REP 每執(zhí)行一次后面的字符串指令后, cx減1, 直至 cx 為0
在本例中, 每次拷貝 sizeof(DWORD) 四個字節(jié), 而堆棧大小是 76(0x4C) 個字節(jié), 故 只需要重復(fù)執(zhí)行 76 / 4 = 19(0x13) 次就可以了

0040102C   mov         ecx,13h           ;

現(xiàn)在終于清楚

00401029   lea         edi,[ebp-4Ch]     ; 將有效的地址 [ebp-0x4Ch] 賦值到 edi
0040102C   mov         ecx,13h           ;
00401031   mov         eax,0CCCCCCCCh    ;
00401036   rep stos    dword ptr [edi]   ;

的作用就是把堆棧的數(shù)據(jù)置為 0xCC;


困了,先去睡下再寫第2集~~

Feedback

# re: 函數(shù)堆棧是這么回事 第1集[未登錄]  回復(fù)  更多評論   

2008-09-26 10:43 by flyswift
很好很強(qiáng)大。LZ繼續(xù)。

# re: 函數(shù)堆棧是這么回事 第1集  回復(fù)  更多評論   

2008-09-26 13:55 by ljbxc
支持,繼續(xù)

# re: 函數(shù)堆棧是這么回事 第1集  回復(fù)  更多評論   

2008-09-26 15:23 by luke
入棧的順序應(yīng)該是j,i吧?

# re: 函數(shù)堆棧是這么回事 第1集  回復(fù)  更多評論   

2008-09-27 16:03 by 908971
mark
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久夜夜夜| 日韩一级不卡| 欧美成人免费全部| 久久网站免费| 美女成人午夜| 欧美日韩一区二区三区| 欧美日韩精品中文字幕| 欧美网站在线观看| 国产精品外国| 在线精品亚洲| av成人免费在线| 亚洲欧美日韩另类精品一区二区三区 | 久久都是精品| 欧美jizz19性欧美| 一本色道久久综合狠狠躁篇怎么玩 | 麻豆成人在线观看| 欧美精品在线播放| 国产精品第2页| 尤物在线精品| 亚洲女人天堂av| 久久久国产一区二区| 免费在线亚洲欧美| 亚洲少妇在线| 久久网站热最新地址| 欧美剧在线观看| 在线不卡中文字幕| 亚洲综合日韩在线| 免费高清在线视频一区·| 99riav国产精品| 久久婷婷国产综合国色天香| 欧美日韩视频不卡| 亚洲国产精品成人久久综合一区| 亚洲一区二区成人| 亚洲成色精品| 亚洲一区二区免费看| 欧美激情成人在线视频| 国模套图日韩精品一区二区| 亚洲一区国产精品| 亚洲国产欧美久久| 久久精品一区二区三区不卡牛牛 | 国产午夜精品久久久久久久| 亚洲精品小视频| 久久综合999| 亚洲一区二区三区激情| 欧美日韩一区在线观看视频| 亚洲人体1000| 亚洲福利av| 免费成人av在线| 在线日韩中文字幕| 老牛影视一区二区三区| 欧美一区二区在线免费观看| 国产精品免费福利| 亚洲欧美国产一区二区三区| 亚洲精品色婷婷福利天堂| 蜜桃av一区| 亚洲理论在线观看| 亚洲欧洲一区二区在线播放| 免费影视亚洲| 最近中文字幕日韩精品| 免费成人激情视频| 久久香蕉国产线看观看av| 精品成人一区二区| 久久成人人人人精品欧| 亚洲欧美日韩在线观看a三区| 国产精品久久久亚洲一区| 欧美一区在线看| 国产精品自在线| 久久亚洲精品欧美| 欧美另类女人| 在线欧美亚洲| 久久久久久国产精品一区| 亚洲制服av| 亚洲视频在线观看一区| 欧美日韩亚洲综合| 亚洲最新在线| 99精品国产高清一区二区| 欧美日韩在线一区二区三区| 日韩午夜在线电影| 亚洲福利专区| 欧美偷拍另类| 久久久久久久久伊人| 久久精品网址| 一本到高清视频免费精品| 一道本一区二区| 国产网站欧美日韩免费精品在线观看| 久久久xxx| 欧美精品色网| 欧美一区免费视频| 久久国内精品视频| 亚洲日韩欧美视频| 亚洲免费中文字幕| 亚洲欧洲日韩综合二区| 亚洲主播在线| 久久久久久久久久久久久久一区| 国产在线播精品第三| 美女黄色成人网| 欧美日本在线播放| 久久久久99精品国产片| 欧美成人有码| 欧美一区亚洲二区| 免费人成精品欧美精品| 亚洲精品久久在线| 亚洲欧美日韩一区| 亚洲承认在线| 一级成人国产| 亚洲人成网站色ww在线| 中文网丁香综合网| 亚洲国产日韩欧美在线图片| 亚洲人成高清| 一色屋精品视频在线看| 亚洲综合色丁香婷婷六月图片| 在线观看欧美精品| 中文一区二区| 亚洲午夜久久久久久久久电影院| 久久国产欧美日韩精品| 中国成人黄色视屏| 亚洲精品美女| 久久久精品动漫| 性做久久久久久免费观看欧美| 欧美久色视频| 久久久亚洲高清| 国产精品久久9| 亚洲精品免费在线播放| 韩日精品视频一区| 亚洲永久精品大片| 一区二区三区色| 欧美高清自拍一区| 男女激情久久| 在线色欧美三级视频| 久久久久免费| 亚洲欧美日韩精品| 欧美性大战久久久久久久蜜臀| 欧美日韩精品免费在线观看视频| 国产尤物精品| 99香蕉国产精品偷在线观看| 亚洲日本在线观看| 欧美成人xxx| 欧美激情精品久久久久久免费印度 | 亚洲第一页自拍| 先锋影音久久久| 欧美中文在线视频| 国产精品一区二区在线观看| 亚洲一线二线三线久久久| 亚洲欧美国产日韩中文字幕| 国产精品乱码一区二区三区| 亚洲图片欧洲图片av| 性伦欧美刺激片在线观看| 国产欧美综合一区二区三区| 亚洲欧美国产不卡| 午夜精品久久| 国产一区二区三区四区hd| 久久精品一区| 最新高清无码专区| 亚洲免费在线播放| 国产一区二区三区在线观看视频| 欧美一区网站| 欧美国产日韩a欧美在线观看| 99国产精品99久久久久久粉嫩| 欧美日韩在线看| 久久超碰97中文字幕| 亚洲国产欧美国产综合一区| 亚洲一区www| 伊人精品成人久久综合软件| 欧美国产第一页| 亚洲视频在线观看网站| 久久免费少妇高潮久久精品99| 亚洲国产精品第一区二区三区| 欧美日韩国产高清视频| 欧美一区影院| 99国产精品久久久久久久成人热| 午夜在线视频观看日韩17c| 狠狠色综合网站久久久久久久| 能在线观看的日韩av| 亚洲自拍偷拍网址| 欧美黄色成人网| 久久国产成人| 一本到12不卡视频在线dvd| 国产综合香蕉五月婷在线| 欧美精品色一区二区三区| 欧美一区二区三区视频| 亚洲毛片在线免费观看| 久久久青草婷婷精品综合日韩 | 欧美日韩小视频| 老司机精品视频网站| 亚洲在线免费观看| 伊人一区二区三区久久精品| 欧美午夜精品久久久久久浪潮| 久久久久久久一区二区| 亚洲天堂av在线免费| 欧美激情亚洲国产| 久久国内精品视频| 日韩视频在线你懂得| 激情视频一区二区| 国产精品一二| 欧美国产日韩xxxxx| 久久久免费精品视频| 欧美另类在线观看| 亚洲免费影视| 一本大道久久a久久综合婷婷| 麻豆成人在线播放|