本次筆記內容:
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+1
到p+9
則跨塊了,訪問時會降低效率,不妥。
之後的內容,如結構數組
、聯合
和練習題
因爲時間原因沒有講,可見ppt。