程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C說話中的數組和指針匯編代碼剖析實例

C說話中的數組和指針匯編代碼剖析實例

編輯:關於C++

C說話中的數組和指針匯編代碼剖析實例。本站提示廣大學習愛好者:(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    ;這個年夜家都熟,不要忘了\0
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=%s\n", chTest);
       return 0;
}

下面有個extern聲明,注解chTest數組是在內部文件中界說過的。chTest界說在inc.h中:

char chTest[10]="123456789";

上述的法式,經編譯後,可以勝利運轉。但假如把白色的代碼改成以下:

extern char *chTest;

這時候,法式在編譯的時刻就會通不外,提醒的毛病信息是:redefinition; different types of indirection,但這時候候並沒有毛病湧現在哪一行的解釋,假如是在開辟一個年夜型工程,那末就不輕易定位成績出在哪一個處所。形成上述毛病的緣由我想年夜家都明確了,就是由於當chTest作為一個指針被援用時,其元素拜訪的方法與數組是分歧的,就算法式能編譯經由過程,在運轉時,也是會湧現毛病。

好了,上述的內容都是小我有感而發,是些簡略零星的器械,笑納。若有哪些處所說的不適合,而望斧正!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved