【彙編語言與計算機系統結構筆記10】C語言數組的彙編訪問:連續存儲、代碼優化、無邊界檢查;結構對齊要求 #簡潔筆記形式

本次筆記內容:
13.數據的機器表示

注:本次筆記開始,我找到了對應內容的課件,請見我於GitHub的CS筆記倉庫因此,爲了節省時間,我只記錄老師上課強調的內容與對應ppt頁碼。

本節課對應幻燈片:彙編語言程序設計-C語言與彙編,第183頁起。

課程流程

數組訪問

首先是基本數據類型數據的內存存儲基本原則數組訪問,“一看便知”,老師沒有做講解。

在第187頁,以C語言聲明數組訪問代碼爲例,觀察其對應的彙編是怎樣的。

在第188頁,給了數組循環示例(X86-32):從C語言到彙編語言。

在第189頁,給了指針循環示例(X86-32):即在C中,用指針訪問數組元素,其對應彙編語言。

嵌套數組

P190,展示了嵌套數組在內存中的排布。對於靜態數組,在編譯時完全瞭解其在內存中分佈,對編譯器有利。

P191進行舉例,訪問嵌套數組中的“行”,並附有彙編代碼。編譯器儘量轉換出 leal 指令進行計算。

P192舉例訪問嵌套數組的單個元素

Multi-Level Array

變量univ是一個指針數組,數組長度爲3,數組
元素長度爲4字節。每個指針指向一個整數數組。

那麼,這三個數組該怎麼在內存中分佈呢?

那麼,該如何訪問呢?

在地址計算時,Mem[Mem[univ+4*index]+4*dig]求取地址值。

  • 首先獲得行地址;
  • 再訪問改行中元素。

要注意,其與嵌套訪問數組不同。 對比可見P195。

N×N Matrix Code三種情況討論

P196討論了三種方陣的情況:N已知N可變,使用偏移方式訪問N可變,直接訪問(已被gcc支持)

接着,以16×16、動態n×n矩陣爲例,進行舉例,有C彙編代碼。

P199給出了一個優化方案的實例:如何取一列?

  • C中使用循環i不變,j爲循環變量;
  • 而編譯器可以對這個過程進行優化。

同理,P201給出了變長矩陣的取列操作。與上一個例子原理是相同的。

P202給了一道反彙編的練習題:本課程中比較強調反彙編的能力。

結構 struct

數組內容結束,進入結構部分P204。

結構就是連續分配的內存區域,內部元素通過名字訪問,且元素可以是不同的數據類型。

課程中所需要討論的爲:如何計算結構中元素的地址?

每個元素在結構中的相對地址在編譯時就已確定。

(結構中)數據存儲位置對齊

在實際中,不同的數據類型有不同的對齊要求。

因此要討論對齊的原則、原因、操作等。從P207開始。

對齊的原因是:計算機訪問內存一般是以內存塊爲單位的,塊的大小是地址對齊的,如4、8、16字節對齊等。如果數據訪問地址跨越“塊”邊界會引起額外的內存訪問。

編譯器的工作就是:在結構的各個元素間插入額外空間來滿足不同元素的對齊要求。

P208-209展示了x86-64下不同元素的對齊要求。

結構的存儲對齊要求

P210:

  • 必須滿足結構中各個元素的對齊要求;
  • 結構自身的對齊要求等同於其各個元素中對齊要
    求最高的那個,設爲K字節;
  • 結構的起始地址與結構長度必須是K的整數倍。

從P210開始有圖形示例,告訴你“對齊”到底是怎麼回事。

大部分情況,爲了滿足對齊要求,會浪費一些 byte 。

結構自身的對齊要求

P213,結構可能要求自己必須是8過4字節的整數倍。

結構內元素不同的先後順序

順序不同,會影響空間利用,因此:儘量把double等長類型放在結構前面,以防止前一個小結構爲了對齊後一個大結構,而浪費許多空間

P213給了很生動的例子。

自問自答:爲什麼例子的反例中,要浪費那麼多空間?我想,因爲內存是分塊的。如果v處於p+1p+9則跨塊了,訪問時會降低效率,不妥。

之後的內容,如結構數組聯合練習題因爲時間原因沒有講,可見ppt。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章