音影先锋亚洲天堂网|电影世界尽头的爱完整版播放|国产 熟女 91|高清无码免费观看欧美日韩|韩国一区二区三区黄色录像|美女亚洲加勒比在线|亚洲综合网 开心五月|7x成人在线入口|成人网站免费日韩毛片区|国产黄片?一级?二级?三级

登錄 免費(fèi)注冊(cè) 首頁 | 行業(yè)黑名單 | 幫助
維庫(kù)電子市場(chǎng)網(wǎng)
技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測(cè)控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng)
驅(qū)動(dòng)編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機(jī) | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計(jì) | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe

看看C語句都生成了什么匯編指令,并有問題請(qǐng)教

作者:wszqw 欄目:單片機(jī)
看看C語句都生成了什么匯編指令,并有問題請(qǐng)教
看看C語句都生成了什么匯編指令

是pc上的X86匯編指令

使用DEV C++編譯


2樓: >>參與討論
wszqw
先看空函數(shù)都生成了什么
空函數(shù)代碼 build by devcpp4990

int main(void){}
main(){}
void main(void){}
int main(int argc,CHAR *argv[])        

//注:以上寫法生成的代碼居然是相同的!


//Assembler code
//Function: main
0x401290 <main>:    PUSH    ebp                  //C函數(shù)中用ebp做指針[基址]對(duì)變量尋址
0x401291 <main+1>:    mov    ebp,esp
0x401293 <main+3>:    sub    esp,0x8              //生成一個(gè)堆?蚣艽娣牛ň植浚┳兞
0x401296 <main+6>:    and    esp,0xfffffff0         //對(duì)齊?
0x401299 <main+9>:    mov    eax,0x0
0x40129e <main+14>:    mov    DWORD PTR [esp-4],eax
0x4012a1 <main+17>:    mov    eax,DWORD PTR [ebp-4]  //這三條指令干啥用?
0x4012a4 <main+20>:    call    0x401710 <_alloca>
0x4012a9 <main+25>:    call    0x401380 <__main>      //這兩個(gè)call做了什么??
0x4012ae <main+30>:    leave                        //釋放堆棧
0x4012af <main+31>:    ret                          //返回


//注:
1。前3條指令相當(dāng)于一條ENTER指令,(與后面的leave相對(duì)應(yīng))。做編譯器的家伙干嘛不這里直接放一條enter指令?

2。0x401296 <main+6>:    and    esp,0xfffffff0
   應(yīng)該是整字長(zhǎng)度對(duì)齊,不知具體什么時(shí)候有作用

3。DWORD PTR [esp-4],eax 中的PTR我猜想是pointer的意思?

4。0x4012a4 <main+20>:    call    0x401710 <_alloca>
   0x4012a9 <main+25>:    call    0x401380 <__main>    
   這兩條call指令都干啥用?
   
   ——這是一個(gè)讓我巨迷惑的問題


3樓: >>參與討論
wszqw
C函數(shù)中一般使用寄存器eax返回參數(shù)
例:

返回0的空函數(shù)
int main(void){return0;}

//Function: main
0x401290 <main>:    PUSH    ebp
0x401291 <main+1>:    mov    ebp,esp
0x401293 <main+3>:    sub    esp,0x8
0x401296 <main+6>:    and    esp,0xfffffff0
0x401299 <main+9>:    mov    eax,0x0
0x40129e <main+14>:    mov    DWORD PTR [esp-4],eax
0x4012a1 <main+17>:    mov    eax,DWORD PTR [ebp-4]
0x4012a4 <main+20>:    call    0x401710 <_alloca>
0x4012a9 <main+25>:    call    0x401380 <__main>
0x4012ae <main+30>:    mov    eax,0x0    //比空函數(shù)多了這條指令, 若改成return 1; 則為mov eax,0x1
0x4012b3 <main+35>:    leave
0x4012b4 <main+36>:    ret


4樓: >>參與討論
wszqw
看一個(gè)實(shí)際例子
這回看一個(gè)實(shí)際例子,求1,2,3的平方和
看看生成了什么指令

//#include <stdio.h>
//#include <stdlib.h>
int square (int);

int main (void)         //求1,2,3的平方和
{
    int i, sum=0;
    for(i=1;i<4;i++)
        sum += square(i);

    return 0;
}

int square(int a)    //求平方
{
    return a*a;
}

///////////////////////////////////////////////////
//Assembler code
//Function: main
0x401290 <main>:    PUSH    ebp
0x401291 <main+1>:    mov    ebp,esp            //esp賦給ebp, 用ebp尋址
0x401293 <main+3>:    sub    esp,0x18        //esp-0x18 生成堆?臻g24bytes(還是20bytes?)
0x401296 <main+6>:    and    esp,0xfffffff0        //屏蔽低4位, 字對(duì)齊
0x401299 <main+9>:    mov    eax,0x0
0x40129e <main+14>:    mov    DWORD PTR [esp-14],eax    
0x4012a1 <main+17>:    mov    eax,DWORD PTR [ebp-12]  //這3條指令不知干啥,估計(jì)跟下面兩條指令有關(guān)
0x4012a4 <main+20>:    call    0x401750 <_alloca>      //問題是,這兩條指令不知他們干了件啥重要的事
0x4012a9 <main+25>:    call    0x4013c0 <__main>       //與系統(tǒng)有關(guān)的?請(qǐng)知道的告訴我,真誠(chéng)感謝!
0x4012ae <main+30>:    mov    DWORD PTR [ebp-8],0x0   //變量sum
0x4012b5 <main+37>:    mov    DWORD PTR [ebp-4],0x1   //變量i
0x4012bc <main+44>:    cmp    DWORD PTR [ebp-4],0x3   //i小于等于3的話
0x4012c0 <main+48>:    jle    0x4012c4 <main+52>      //執(zhí)行循環(huán)
0x4012c2 <main+50>:    jmp    0x4012dd <main+77>      //否則就退出
0x4012c4 <main+52>:    mov    eax,DWORD PTR [ebp-4]   //把i傳給被調(diào)用函數(shù),
0x4012c7 <main+55>:    mov    DWORD PTR [esp],eax     //也就是放入DWORD PTR [esp]中
0x4012ca <main+58>:    call    0x4012e4 <square>       //調(diào)用函數(shù)int square(int a)
0x4012cf <main+63>:    mov    edx,eax                 //從寄存器eax中取出返回值放到edx中
0x4012d1 <main+65>:    lea    eax,[ebp-8]             //取變量sum的地址
0x4012d4 <main+68>:    add    DWORD PTR [eax],edx     //返回值加入到sum中
0x4012d6 <main+70>:    lea    eax,[ebp-4]
0x4012d9 <main+73>:    inc    DWORD PTR [eax]         //變量i加1(i++)
0x4012db <main+75>:    jmp    0x4012bc <main+44>
0x4012dd <main+77>:    mov    eax,0x0                 //返回0
0x4012e2 <main+82>:    leave
0x4012e3 <main+83>:    ret

//Function: square

0x4012e4 <square>:    PUSH    ebp
0x4012e5 <square+1>:    mov    ebp,esp
0x4012e7 <square+3>:    mov    eax,DWORD PTR [ebp+8]    //變量a在[esp+8]中,即主函數(shù)中的DWORD PTR [esp]單元
0x4012ea <square+6>:    imul    eax,DWORD PTR [ebp+8]   //函數(shù)返回值放在cpu寄存器eax中
0x4012ee <square+10>:    pop    ebp
0x4012ef <square+11>:    ret

* - 本貼最后修改時(shí)間:2005-8-2 1:27:27 修改者:wszqw

5樓: >>參與討論
wszqw
少使用中間變量,指令簡(jiǎn)潔
少使用中間變量,指令簡(jiǎn)潔

int square(int a)
{
    return a*a;
}
PUSH    ebp
mov    ebp,esp
mov    eax,DWORD PTR [ebp+8]    //vairable a located in DWORD PTR [esp+8]
imul    eax,DWORD PTR [ebp+8]   //變量a在[ebp+8]中,函數(shù)返回值放在cpu寄存器eax中
pop    ebp
ret

使用中間變量,有多余指令

int square(int a)
{   int r;
    r = a*a;
    return r;  //a*a;
}
PUSH    ebp
mov    ebp,esp
sub    esp,0x4                 //為中間變量開辟存儲(chǔ)空間
mov    eax,DWORD PTR [ebp+8]     //變量a在[ebp+8]中
imul    eax,DWORD PTR [ebp+8]
mov    DWORD PTR [ebp-4],eax     //變量r在[ebp-4]中
mov    eax,DWORD PTR [ebp-4]     //這兩條指令純屬多余
leave
ret


6樓: >>參與討論
wszqw
查看
我用的是dev c++,用查看cpu窗口得到匯編代碼的。別的招就不會(huì)了
有沒有更好的辦法把匯編代碼打印出來?

怎么追蹤0x401710 <_alloca>和0x401380 <__main>位置?
想去瞧瞧到底有什么東東


7樓: >>參與討論
wszqw
發(fā)現(xiàn)看c生成的匯編代碼還是有幫助的
對(duì)變量存儲(chǔ)、參數(shù)傳遞、子程序結(jié)構(gòu)等更好了解

尤其是它的函數(shù)堆棧的創(chuàng)建,原來是這樣搞得,服了



參與討論
昵稱:
討論內(nèi)容:
 
 
相關(guān)帖子
MCU51-63K仿真頭是不是一定不能仿真串口?
89c2051能不能輸出125k方波?24M晶振
求救.
51
關(guān)于2051的封裝和價(jià)格
免費(fèi)注冊(cè)為維庫(kù)電子開發(fā)網(wǎng)會(huì)員,參與電子工程師社區(qū)討論,點(diǎn)此進(jìn)入


Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號(hào)