C語言中的數組和指標彙編程式碼分析執行個體

來源:互聯網
上載者:User

   這篇文章主要介紹了C語言中的數組和指標彙編程式碼分析執行個體,本文用一則C語言例子來得到對應的彙編代碼,並一一註解每句彙編代碼的含義,需要的朋友可以參考下

  今天看《程式員面試寶典》時偶然看到講數組和指標的存取效率,閑著無聊,就自己寫了段小代碼,簡單分析一下C語言背後的彙編,可能很多人只注重C語言,但在實際應用當中,當出現問題時,有時候還是通過分析彙編代碼能夠解決問題。本文只是為初學者,大牛可以飄過~

  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函數中靠前的部分隨便一行F9設定斷點->編譯->F5 在調試介面中右鍵->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 ;壓入程式中用到的寄存器,以便恢複

  00401019 lea edi,[ebp-54h]

  0040101C mov ecx,15h

  00401021 mov eax,0CCCCCCCCh

  00401026 rep stos dword ptr [edi] ;棧頂與棧幀之間的資料填充為0xcc,相當於彙編中的int 3,這是因為debug模式下把Stack上的變數都初始化為0xcc,檢查未初始化的問題

  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”是字串常量,儲存在地址0042201c處,ebp-10是為數組C分配的空間的首地址,空間大小從ebp-0x10到ebp-0x04,共12個位元組。本句中先把“1234”這4個位元組拷貝到數組C中

  00401034 mov ecx,dword ptr [string "1234567890" 4 (00422020)]

  0040103A mov dword ptr [ebp-0Ch],ecx ;作用同上,把“5678”這4個位元組拷貝到數組C中

  0040103D mov dx,word ptr [string "1234567890" 8 (00422024)]

  00401044 mov word ptr [ebp-8],dx ;作用同上,把“90”這2個位元組拷貝到C中

  00401048 mov al,[string "1234567890" 0Ah (00422026)]

  0040104D mov byte ptr [ebp-6],al ;這個大家都熟,不要忘了

  10: char *p = "1234567890";

  00401050 mov dword ptr [ebp-14h],offset string "1234567890" (0042201c) ;ebp-0x14是為指標p分配的空間地址,大小是4個位元組,地址中的值是字串“1234567890”的首地址

  11: a = c[1];

  00401057 mov cl,byte ptr [ebp-0Fh] ;這裡是重點,因為數組C在棧上連續儲存,很容易根據ebp找到第其中一個字元的地址,並取值,賦給cl

  0040105A mov byte ptr [ebp-4],cl ;完成賦值

  12: a = p[1];

  0040105D mov edx,dword ptr [ebp-14h] ;這裡與上面就有區別,因為根據ebp只知道指標p的值,先得到p的值,即先得到一個指標

  00401060 mov al,byte ptr [edx 1] ;根據得到的指標間接的找到字串中的一個字元

  00401063 mov byte ptr [ebp-4],al

  13: return 0;

  00401066 xor eax,eax ;eax清0,作為main函數的傳回值

  14: }

  00401068 pop edi

  00401069 pop esi

  0040106A pop ebx

  0040106B mov esp,ebp

  0040106D pop ebp ;恢複ebp

  0040106E ret

  好了,可以看到,用數組訪問元素,只需2步,而用指標時要3步。可見數組和指標並不相同,有時候大家都認為可以把數組的名稱看成一個指標,這種想法有時候沒錯,但有時候卻會出錯。我再舉一個簡單的例子,而下面的這個例子可能是大家在開發過程中經常會碰到的問題。

  在檔案test.cpp中:

   代碼如下:

  #include "stdafx.h"

  #include "inc.h"

  extern char chTest[10];

  int main(int argc, char* argv[])

  {

  printf("chTest=%sn", chTest);

  return 0;

  }

  上面有個extern聲明,表明chTest數組是在外部檔案中定義過的。chTest定義在inc.h中:

   代碼如下:

  char chTest[10]="123456789";

  上述的程式,經編譯後,可以成功運行。但如果把紅色的代碼改成如下:

   代碼如下:

  extern char *chTest;

  這時,程式在編譯的時候就會通不過,提示的錯誤資訊是:redefinition; different types of indirection,但這時候並沒有錯誤出現在哪一行的說明,如果是在開發一個大型工程,那麼就不容易定位問題出在哪個地方。造成上述錯誤的原因我想大家都明白了,就是因為當chTest作為一個指標被引用時,其元素訪問的方式與數組是不同的,就算程式能編譯通過,在運行時,也是會出現錯誤。

  好了,上述的內容都是個人有感而發,是些簡單零碎的東西,笑納。如有哪些地方說的不合適,而望指正!

相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。