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

沒畫完的畫

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

為了弄清楚函數的堆棧,Google了一下,找到下面代碼作為實驗
 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 進行調試
vc6 中在 fun1 設置斷點,按F5,  到達斷點后,選擇菜單 view -> Disassembly 就可以看到代碼對應的匯編語句

調用 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

從內存存放的內容可知, i, j 分別存放于 0x0012FF70H, 0x0012FF74H
分別占了四個字節

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

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

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

push 進去的數是 0x004010E4, 再看回調用 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 進去的數剛好是 call 指令后面的指令地址 0x004010E4  

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

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

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

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

在DEBUG版本中,VC匯編程序會產生一個函數跳轉指令表,
該表的每個表項存放一個函數的跳轉指令。
程序中的函數調用就是利用這個表來實現跳轉到相應函數的入口地址。

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


接下來, 應該看一下 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 函數層的 棧內存基地址
esp 為 當前的棧頂地址

00401020   push        ebp
00401021   mov         ebp,esp

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

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

接著又把 ebx, esi, edi 分別入棧, 目的是為了保存 main 函數層的相關內容
00401026   push        ebx
00401027   push        esi
00401028   push        edi

最后用0xCC初始化上述為func1()函數層所分配的棧內存的每個字節。這里每一步用F11單步跟蹤,棧內存的變化你會看得更清楚。
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(字節)或AX(字)中的數據存儲到DI為目的串地址指針所尋址的存儲器單元中去.指針DI將根據DF的值進行自動調整.
由于上面的指令是 dword ptr 類型
dword 表示雙字 ptr 表示取首地址
那么 stos    dword ptr [edi] 執行的操作就是
將 ES:[DI]←AX,DI←DI±4   (DI 加或減是由 DF 標志位確定的)
如果是 那么 stos word ptr [edi] 的話那么就是
將 ES:[DI]←AL,DI←DI±2   (DI 加或減是由 DF 標志位確定的)
不然推出 stos BYTE ptr [edi]

注:
DF:方向標志DF位用來決定在串操作指令執行時有關指針寄存器發生調整的方向。

重復前綴
格式: REP           ;CX<>0 重復執行字符串指令

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

0040102C   mov         ecx,13h           ;

現在終于清楚

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

的作用就是把堆棧的數據置為 0xCC;


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

Feedback

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

2008-09-26 10:43 by flyswift
很好很強大。LZ繼續。

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

2008-09-26 13:55 by ljbxc
支持,繼續

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

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

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

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>
            亚洲私人影院在线观看| 99re视频这里只有精品| 性18欧美另类| 国产一区二区三区日韩欧美| 久久久国产精彩视频美女艺术照福利| 亚洲伊人第一页| 国内成人精品视频| 国产日产欧美a一级在线| 久久精品国产2020观看福利| 久久久.com| 艳女tv在线观看国产一区| 亚洲天堂av图片| 国产主播精品| 亚洲毛片av| 国产日韩欧美高清免费| 嫩草影视亚洲| 欧美日韩一区综合| 久久一区二区三区四区| 欧美精品v日韩精品v国产精品| 亚洲最新在线视频| 欧美影片第一页| 亚洲乱码国产乱码精品精可以看| 99国内精品久久| 亚洲欧美国产精品专区久久| 亚洲第一免费播放区| 夜色激情一区二区| 伊人精品久久久久7777| 日韩一级大片| 在线日韩中文| 亚洲欧美日本视频在线观看| 99爱精品视频| 欧美中文字幕| 欧美精品videossex性护士| 久久九九免费| 国产精品国产福利国产秒拍| 欧美不卡福利| 国产日韩欧美一区二区三区四区| 亚洲激情不卡| 国产乱码精品一区二区三区五月婷 | 亚洲日本中文字幕区| 国产欧美综合一区二区三区| 亚洲人www| 亚洲国产一区二区三区青草影视| 亚洲欧美日韩精品久久久久| 99国产精品久久久| 久久中文精品| 久久免费黄色| 国产日本欧美视频| 亚洲欧美另类中文字幕| 在线亚洲欧美视频| 欧美国产专区| 亚洲福利视频三区| 一区二区在线看| 欧美专区日韩专区| 久久国产精品72免费观看| 国产精品成人观看视频免费 | 一本色道久久综合亚洲精品按摩| 亚洲国产精品一区二区第一页| 欧美一二区视频| 欧美一区二区三区的| 国产精品草草| 亚洲午夜精品国产| 午夜在线精品| 国产日韩欧美夫妻视频在线观看| 亚洲欧美日韩网| 欧美专区中文字幕| 国产伦精品一区二区三区免费| 99国产精品久久久久久久久久| 亚洲精品视频免费在线观看| 欧美成人在线网站| 亚洲国产成人在线视频| 亚洲精品视频在线播放| 免费在线成人av| 亚洲精品少妇网址| 午夜日韩福利| 国产一区在线免费观看| 欧美一区二区精品| 欧美jizzhd精品欧美巨大免费| 在线精品亚洲一区二区| 久热这里只精品99re8久| 在线日韩视频| 欧美a级理论片| 亚洲精品资源美女情侣酒店| 亚洲免费伊人电影在线观看av| 国产精品尤物福利片在线观看| 午夜激情亚洲| 蜜臀av性久久久久蜜臀aⅴ| 亚洲福利精品| 久久亚洲春色中文字幕| 亚洲国产高清高潮精品美女| 欧美日韩极品在线观看一区| 亚洲欧美www| 欧美激情导航| 午夜精品久久久久久久白皮肤 | 在线观看亚洲精品视频| 欧美日韩另类字幕中文| 欧美一区二区三区免费观看| 亚洲国产美国国产综合一区二区| 在线亚洲一区观看| 国内自拍视频一区二区三区| 欧美另类在线播放| 久久国产精品亚洲77777| 亚洲精品日韩综合观看成人91| 欧美在线www| 99国产精品99久久久久久| 国内久久视频| 国产精品久久二区| 欧美jizzhd精品欧美喷水| 亚洲综合日韩在线| 亚洲人成网站精品片在线观看 | 亚洲精品国产拍免费91在线| 国产精品电影观看| 免费永久网站黄欧美| 欧美一区二区三区在线观看视频 | 欧美亚洲一区二区在线| 亚洲精品免费看| 老鸭窝毛片一区二区三区| 亚洲一区二区三区精品在线| 亚洲国产精品成人综合色在线婷婷| 国产精品久久77777| 欧美精品aa| 欧美成人一区二区在线| 久久精品亚洲一区二区| 亚洲综合首页| 中文国产成人精品久久一| 亚洲国产一二三| 欧美va天堂在线| 国产精品观看| 欧美日韩一区二区免费在线观看 | 欧美在线综合| 亚洲一区久久| 亚洲天堂av在线免费观看| 亚洲精品少妇| 日韩视频在线播放| 亚洲久久视频| 一区二区三区国产| 一本色道久久| 一区二区三区视频在线看| 99re6这里只有精品视频在线观看 99re6这里只有精品 | 欧美日韩在线一区二区| 欧美精品久久久久久久久老牛影院| 久久亚洲私人国产精品va媚药| 欧美在线视频网站| 久久精品中文字幕一区二区三区| 欧美亚洲免费电影| 欧美有码视频| 久久综合狠狠综合久久综青草 | 亚洲图片激情小说| 日韩系列在线| 亚洲主播在线播放| 翔田千里一区二区| 欧美丝袜一区二区三区| 欧美视频二区36p| 国产精品永久免费视频| 国产自产女人91一区在线观看| 韩国精品久久久999| 在线视频国内自拍亚洲视频| 91久久精品国产91性色| 亚洲精品久久久久久久久久久| 夜夜精品视频一区二区| 亚洲制服av| 久久久在线视频| 欧美成人精品一区二区| 亚洲免费观看高清完整版在线观看熊| 亚洲精选一区二区| 欧美一区二区观看视频| 欧美sm极限捆绑bd| 国产精品高清一区二区三区| 黄色一区二区在线观看| 亚洲乱码一区二区| 香蕉免费一区二区三区在线观看| 久久蜜桃香蕉精品一区二区三区| 亚洲成色999久久网站| 一区二区三区日韩欧美| 久久久久9999亚洲精品| 欧美高清视频一区二区三区在线观看 | 欧美激情第10页| 午夜精品福利视频| 美女性感视频久久久| 欧美性大战久久久久久久| 激情校园亚洲| 亚洲综合二区| 国产综合精品| 一区二区三区国产精华| 玖玖国产精品视频| 亚洲图片在区色| 欧美精品www在线观看| 国产一区999| 亚洲一区二区视频在线| 欧美刺激性大交免费视频 | 免费在线亚洲欧美| 亚洲欧美经典视频| 欧美人与性禽动交情品 | 一区在线观看视频| 亚洲无毛电影| 亚洲国产一区二区三区青草影视| 久久9热精品视频| 国产精品一区二区三区四区 | 欧美3dxxxxhd| 久久国产高清|