C語(yǔ)言中的數(shù)組和指針匯編代碼分析實(shí)例
今天看《程序員面試寶典》時(shí)偶然看到講數(shù)組和指針的存取效率,閑著無(wú)聊,就自己寫了段小代碼,簡(jiǎn)單分析一下C語(yǔ)言背后的匯編,可能很多人只注重C語(yǔ)言,但在實(shí)際應(yīng)用當(dāng)中,當(dāng)出現(xiàn)問(wèn)題時(shí),有時(shí)候還是通過(guò)分析匯編代碼能夠解決問(wèn)題。本文只是為初學(xué)者,大??梢燥h過(guò)~
C源代碼如下:
#include "stdafx.h"
int main(int argc, char* argv[])
{
char a=1;
char c[] = "1234567890";
char *p = "1234567890";
a = c[1];
a = p[1];
return 0;
}
在VC6.0下查看匯編代碼步驟:
在main函數(shù)中靠前的部分隨便一行F9設(shè)置斷點(diǎn)->編譯->F5 在調(diào)試界面中右鍵->Go to disassembly
Debug匯編代碼(已加注釋):
4: #include "stdafx.h"
5:
6: int main(int argc, char* argv[])
7: {
00401010 push ebp
00401011 mov ebp,esp ;保存棧幀
00401013 sub esp,54h ;抬高棧頂
00401016 push ebx
00401017 push esi
00401018 push edi ;壓入程序中用到的寄存器,以便恢復(fù)
00401019 lea edi,[ebp-54h]
0040101C mov ecx,15h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi] ;棧頂與棧幀之間的數(shù)據(jù)填充為0xcc,相當(dāng)于匯編中的int 3,這是因?yàn)閐ebug模式下把Stack上的變量都初始化為0xcc,檢查未初始化的問(wèn)題
8: char a=1;
00401028 mov byte ptr [ebp-4],1 ;ebp-4是為變量a分配的空間地址
9: char c[] = "1234567890";
0040102C mov eax,[string "1234567890" (0042201c)]
00401031 mov dword ptr [ebp-10h],eax ;“1234567890”是字符串常量,存儲(chǔ)在地址0042201c處,ebp-10是為數(shù)組C分配的空間的首地址,空間大小從ebp-0x10到ebp-0x04,共12個(gè)字節(jié)。本句中先把“1234”這4個(gè)字節(jié)拷貝到數(shù)組C中
00401034 mov ecx,dword ptr [string "1234567890" 4 (00422020)]
0040103A mov dword ptr [ebp-0Ch],ecx ;作用同上,把“5678”這4個(gè)字節(jié)拷貝到數(shù)組C中
0040103D mov dx,word ptr [string "1234567890" 8 (00422024)]
00401044 mov word ptr [ebp-8],dx ;作用同上,把“90”這2個(gè)字節(jié)拷貝到C中
00401048 mov al,[string "1234567890" 0Ah (00422026)]
0040104D mov byte ptr [ebp-6],al ;這個(gè)大家都熟,不要忘了\0
10: char *p = "1234567890";
00401050 mov dword ptr [ebp-14h],offset string "1234567890" (0042201c) ;ebp-0x14是為指針p分配的空間地址,大小是4個(gè)字節(jié),地址中的值是字符串“1234567890”的首地址
11: a = c[1];
00401057 mov cl,byte ptr [ebp-0Fh] ;這里是重點(diǎn),因?yàn)閿?shù)組C在棧上連續(xù)存儲(chǔ),很容易根據(jù)ebp找到第其中一個(gè)字符的地址,并取值,賦給cl
0040105A mov byte ptr [ebp-4],cl ;完成賦值
12: a = p[1];
0040105D mov edx,dword ptr [ebp-14h] ;這里與上面就有區(qū)別,因?yàn)楦鶕?jù)ebp只知道指針p的值,先得到p的值,即先得到一個(gè)指針
00401060 mov al,byte ptr [edx 1] ;根據(jù)得到的指針間接的找到字符串中的一個(gè)字符
00401063 mov byte ptr [ebp-4],al
13: return 0;
00401066 xor eax,eax ;eax清0,作為main函數(shù)的返回值
14: }
00401068 pop edi
00401069 pop esi
0040106A pop ebx
0040106B mov esp,ebp
0040106D pop ebp ;恢復(fù)ebp
0040106E ret
好了,可以看到,用數(shù)組訪問(wèn)元素,只需2步,而用指針時(shí)要3步??梢?jiàn)數(shù)組和指針并不相同,有時(shí)候大家都認(rèn)為可以把數(shù)組的名稱看成一個(gè)指針,這種想法有時(shí)候沒(méi)錯(cuò),但有時(shí)候卻會(huì)出錯(cuò)。我再舉一個(gè)簡(jiǎn)單的例子,而下面的這個(gè)例子可能是大家在開發(fā)過(guò)程中經(jīng)常會(huì)碰到的問(wèn)題。
在文件test.cpp中:
#include "stdafx.h"
#include "inc.h"
extern char chTest[10];
int main(int argc, char* argv[])
{
printf("chTest=%s\n", chTest);
return 0;
}
上面有個(gè)extern聲明,表明chTest數(shù)組是在外部文件中定義過(guò)的。chTest定義在inc.h中:
char chTest[10]="123456789";
上述的程序,經(jīng)編譯后,可以成功運(yùn)行。但如果把紅色的代碼改成如下:
extern char *chTest;
這時(shí),程序在編譯的時(shí)候就會(huì)通不過(guò),提示的錯(cuò)誤信息是:redefinition; different types of indirection,但這時(shí)候并沒(méi)有錯(cuò)誤出現(xiàn)在哪一行的說(shuō)明,如果是在開發(fā)一個(gè)大型工程,那么就不容易定位問(wèn)題出在哪個(gè)地方。造成上述錯(cuò)誤的原因我想大家都明白了,就是因?yàn)楫?dāng)chTest作為一個(gè)指針被引用時(shí),其元素訪問(wèn)的方式與數(shù)組是不同的,就算程序能編譯通過(guò),在運(yùn)行時(shí),也是會(huì)出現(xiàn)錯(cuò)誤。
好了,上述的內(nèi)容都是個(gè)人有感而發(fā),是些簡(jiǎn)單零碎的東西,笑納。如有哪些地方說(shuō)的不合適,而望指正!
欄 目:C語(yǔ)言
下一篇:C++實(shí)現(xiàn)簡(jiǎn)單遺傳算法
本文標(biāo)題:C語(yǔ)言中的數(shù)組和指針匯編代碼分析實(shí)例
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/3064.html
您可能感興趣的文章
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用函數(shù)刪除字符
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)式函數(shù)庫(kù)
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)數(shù)怎么表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段函數(shù)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排序法函數(shù)
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段函數(shù)
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎么打出三角函數(shù)的值
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求階乘


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10delphi制作wav文件的方法
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文