中文字幕 另类精品,亚洲欧美一区二区蜜桃,日本在线精品视频免费,孩交精品乱子片免费

<sup id="3hn2b"></sup>

    1. <sub id="3hn2b"><ol id="3hn2b"></ol></sub><legend id="3hn2b"></legend>

      1. <xmp id="3hn2b"></xmp>

      2. 新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 匯編技術(shù)內(nèi)幕(4)

        匯編技術(shù)內(nèi)幕(4)

        作者: 時(shí)間:2016-11-24 來(lái)源:網(wǎng)絡(luò) 收藏
        兩個(gè)以上的局部變量棧分配

        程序如下:
        # vi test3.c
        int main()
        {
        int i, j=2, k=4;
        i=3;
        i=++i;
        k=i+j+k;
        return k;
        }

        本文引用地址:http://www.antipu.com.cn/article/201611/320806.htm

        編譯該程序后,用mdb反匯編得出如下結(jié)果:
        # gcc test3.c -o test3
        # mdb test3
        Loading modules: [ libc.so.1 ]
        > main::dis
        main: pushl %ebp
        main+1: movl %esp,%ebp ; main至main+1,創(chuàng)建Stack Frame
        main+3: subl $0x18,%esp ; 為局部變量i,j,k分配棧空間,并保證棧16字節(jié)對(duì)齊
        main+6: andl $0xf0,%esp
        main+9: movl $0,%eax
        main+0xe: subl %eax,%esp ; main+6至main+0xe,再次保證棧16字節(jié)對(duì)齊
        main+0x10: movl $2,-8(%ebp) ; j=2
        main+0x17: movl $4,-0xc(%ebp) ; k=4
        main+0x1e: movl $3,-4(%ebp) ; i=3
        main+0x25: leal -4(%ebp),%eax ; 將i的地址裝入到EAX
        main+0x28: incl (%eax) ; i++
        main+0x2a: movl -8(%ebp),%eax ; 將j的值裝入到 EAX
        main+0x2d: movl -4(%ebp),%edx ; 將i的值裝入到 EDX
        main+0x30: addl %eax,%edx ; j+i,結(jié)果存入EDX
        main+0x32: leal -0xc(%ebp),%eax ; 將k的地址裝入到EAX
        main+0x35: addl %edx,(%eax) ; i+j+k,結(jié)果存入地址ebp-0xc即k中
        main+0x37: movl -0xc(%ebp),%eax ; 將k的值裝入EAX,作為返回值
        main+0x3a: leave ; 撤銷Stack Frame
        main+0x3b: ret ; main函數(shù)返回
        >


        問(wèn)題:為什么3個(gè)變量分配了0x18字節(jié)的棧空間?
        在2個(gè)變量的時(shí)候,分配??臻g的指令是:subl $8,%esp
        而在3個(gè)局部變量的時(shí)候,分配棧空間的指令是:subl $0x18,%esp
        3個(gè)整型變量只需要0xc字節(jié),為何實(shí)際上分配了0x18字節(jié)呢?
        答案就是:保持16字節(jié)棧對(duì)齊。
        gcc默認(rèn)的編譯是要16字節(jié)棧對(duì)齊的,subl $8,%esp會(huì)使棧16字節(jié)對(duì)齊,而8字節(jié)空間只能滿足2個(gè)局部變量,如果再分配4字節(jié)滿足第3個(gè)局部變量的話,那棧地址就不再16字節(jié)對(duì)齊的,而同時(shí)滿足空間需要而且保持16字節(jié)棧對(duì)齊的最接近的就是0x18。
        如果,各定義一個(gè)50字節(jié)和100字節(jié)的字符數(shù)組,在這種情況下,實(shí)際分配多少??臻g呢?答案是0x8+0x40+0x70,即184字節(jié)。
        下面動(dòng)手驗(yàn)證一下:
        # vi test4.c
        int main()
        {
        char str1[50];
        char str2[100];
        return 0;
        }
        # mdb test4
        Loading modules: [ libc.so.1 ]
        > main::dis
        main: pushl %ebp
        main+1: movl %esp,%ebp
        main+3: subl $0xb8,%esp ; 為兩個(gè)字符數(shù)組分配??臻g,同時(shí)保證16字節(jié)對(duì)齊
        main+9: andl $0xf0,%esp
        main+0xc: movl $0,%eax
        main+0x11: subl %eax,%esp
        main+0x13: movl $0,%eax
        main+0x18: leave
        main+0x19: ret
        > 0xb8=D ; 16進(jìn)制換算10進(jìn)制
        184
        > 0x40+0x70+0x8=X ; 表達(dá)式計(jì)算,結(jié)果指定為16進(jìn)制
        b8
        >


        問(wèn)題:定義了多個(gè)局部變量時(shí),棧分配順序是怎樣的?
        局部變量棧分配的順序是按照變量聲明先后的順序,同一行聲明的變量是按照從左到右的順序入棧的,在test2.c中,變量聲明如下:
        int i, j=2, k=4;
        而反匯編的結(jié)果中:
        movl $2,-8(%ebp) ; j=2
        movl $4,-0xc(%ebp) ; k=4
        movl $3,-4(%ebp) ; i=3
        其中不難看出,i,j,k的棧中的位置如下圖:
        +----------------------------+------> 高地址
        | EIP (_start函數(shù)的返回地址) |
        +----------------------------+
        | EBP (_start函數(shù)的EBP) | <------ main函數(shù)的EBP指針(即SFP框架指針)
        +----------------------------+
        | i (EBP-4) |
        +----------------------------+
        | j (EBP-8) |
        +----------------------------+
        | k (EBP-0xc) |
        +----------------------------+------> 低地址



        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉