一道數組指針題搞清楚x86內存

后續文章也同時遷移至個人博客 http://kimihe.com/

參考: iOS 最詳細的解析(數組與指針)筆試題,并做了改進。

引題

先來看一下這道題目,如下代碼的輸出結果是什么?

short arrayName[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *q = (int *)(&arrayName+1);
printf("*(q-2):%d\n", *(q-2));

在看后文的解釋前,不妨自己思考一下。

.
.
.
.
.
.
.
.
.
.
.
.
.

好了,相信你已經思考過了,我們來揭曉結果,結果是令人匪夷所思的458758,答對了嗎?也許你會有疑惑,那么請看下面的注解,在其中增加了些許解釋代碼,并在關鍵代碼后有注釋。

詳細注釋解答:

short arrayName[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int i = 0; i < 10; i++) {
    printf("arr%d addr:%p\n", i, arrayName+i);
}
//&arratName是short(*)[10]類型
short *sp1 = (short *)&arrayName+2; //short(*)[10]先轉short*,再移動2個short*位(4B)
short *sp2 = (short *)(&arrayName+2);//short(*)[10]先移動2個數組位(20個short*: 40B->0x28),再轉short*型
printf("sp1:%p\nsp2:%p\n", sp1, sp2);

short *p = (short *)(&arrayName+1);//short(*)[10]先移動1個數組位(10個short*: 20B->0x14),再轉short*型
int *q = (int *)(&arrayName+1);//short(*)[10]先移動1個數組位(10個short*: 20B->0x14),再轉int*型
printf("p: %p\nq: %p\n", p, q);
printf("p-2:%p\nq-2:%p\n", p-2, q-2);

//q-2:移動2個short*(4B), p-2:移動2個int*(8B)
//x86是小端字節序: 0x0007 0006 -> 7*256*256+6=458758
printf("*(p-2):%d\n*(q-2):%d", *(p-2), *(q-2));

內存地址分配圖:

內存地址分配圖.png

重點:

  • 字節序
  • 內存地址分配
  • 類型轉換

補充

最后我們通過匯編,來深入理解一下如下幾行代碼的含義:

int *p = NULL;
p = (int *)&arrayName;
p = (int *)(&arrayName+1);

對應的匯編分別為:

匯編代碼.png

如圖三個紅圈,這邊是AT&T的匯編格式,我們還是以更好看的intel的樣式來說明:

  • 第一個紅圈,左邊的$0x00立即數賦給[rbp-0x28]這個內存地址,0x00就是NULL的值,而[rbp-0x28]內存地址就是指針p的值(不是*p)。
  • 第二個紅圈,rcx寄存器中含有arrayName數組的首地址(注意:arrayName+0&arrayName取得的地址是相同的),賦給rdxrdx在把它賦給[rbp-0x28],即賦給指針p
  • 第三個紅圈,第一句中,$0x14立即數就是十進制的20,表明10個short*型,因為每個short *占2B。$0x14賦給rcx寄存器,rcx再賦給指針p,最終導致前文所說的,所謂移動整個數組位,從第0個元素移到了第11個元素(雖然數組并沒有第11個元素,但位置的移動可以這樣理解)。

That's all. Thanks for reading.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 指針是C語言中廣泛使用的一種數據類型。 運用指針編程是C語言最主要的風格之一。利用指針變量可以表示各種數據結構; ...
    朱森閱讀 3,473評論 3 44
  • 多線程、特別是NSOperation 和 GCD 的內部原理。運行時機制的原理和運用場景。SDWebImage的原...
    LZM輪回閱讀 2,040評論 0 12
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,381評論 25 708
  • ———————————————回答好下面的足夠了---------------------------------...
    恒愛DE問候閱讀 1,759評論 0 4
  • (原文:http://codejust.top/ubuntu14-04-install-elasticsearch...
    codjust閱讀 6,612評論 6 12