|
|||||||||||
| 技術(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語句都生成了什么匯編指令 是pc上的X86匯編指令 使用DEV C++編譯 |
| 2樓: | >>參與討論 |
| 作者: wszqw 于 2005/8/2 1:24:00 發(fā)布:
先看空函數(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 于 2005/8/2 1:25:00 發(fā)布:
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 于 2005/8/2 1:26:00 發(fā)布:
看一個(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 于 2005/8/2 1:28:00 發(fā)布:
少使用中間變量,指令簡(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 于 2005/8/2 1:31:00 發(fā)布:
查看 我用的是dev c++,用查看cpu窗口得到匯編代碼的。別的招就不會(huì)了 有沒有更好的辦法把匯編代碼打印出來? 怎么追蹤0x401710 <_alloca>和0x401380 <__main>位置? 想去瞧瞧到底有什么東東 |
|
| 7樓: | >>參與討論 |
| 作者: wszqw 于 2005/8/2 1:36:00 發(fā)布:
發(fā)現(xiàn)看c生成的匯編代碼還是有幫助的 對(duì)變量存儲(chǔ)、參數(shù)傳遞、子程序結(jié)構(gòu)等更好了解 尤其是它的函數(shù)堆棧的創(chuàng)建,原來是這樣搞得,服了 |
|
|
|
| 免費(fèi)注冊(cè)為維庫(kù)電子開發(fā)網(wǎng)會(huì)員,參與電子工程師社區(qū)討論,點(diǎn)此進(jìn)入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號(hào) |