位元組對齊是怎麼回事?

2020-07-16 10:04:21
由於C語言是一門接近底層硬體的程式語言,它能直接對記憶體地址進行存取(當前大部分處理器在作業系統的應用層所存取到的邏輯地址,而部分嵌入式系統由於不含帶記憶體管理單元,因此可直接存取實體地址)。

在計算機中,所謂“地址”就是用來標識儲存單元的一個編號,就好比我們住房的門牌號。沒有門牌號,快遞就沒法發貨;如果門牌號記錯了,那麼快遞就會把貨物送錯地方。

計算機中的地址也是一樣,我們為了要存取記憶體中特定單元的一個資料,那麼我們首先要獲悉該資料所在的地址,然後我們通過這個地址來存取它。

存取記憶體,我們也簡稱為“訪存”(Memory Access)。存取地址,我們也簡稱為“定址”(Addressing)。

一般計算機架構中都會有地址匯流排和資料匯流排,CPU 先通過地址匯流排傳送定址信號,以指定所要存取記憶體單元的地址。然後再通過資料匯流排向該地址讀寫資料,這樣就完成了一次訪存操作。這好比於快遞送貨,我們先打電話告訴快遞通訊地址,然後快遞員把貨送到該地址(寫資料),或者去該地址拿貨(讀資料)送到別家。

一般對於 32 位系統來說,處理器一次可存取 1個(8位元)位元組、2 個位元組或 4 個位元組。當存取單個位元組時,對 CPU 不做對齊限制;而當存取多個位元組時,比如要存取 N 個位元組,由於計算機匯流排設計等諸多因素,要求 CPU 所存取的起始地址滿足 N 個位元組的倍數來存取記憶體。如果在存取記憶體時沒有按照特定要求做位元組對齊,那麼可能會引發訪存效能問題,甚至直接導致定址錯誤而引發異常(引發異常後通常會導致當前應用意外退出,在嵌入式系統中可能就直接宕機或復位)。

下面我們給出一張圖來描述,看看一般對 32 位系統而言如何正確地做到訪存位元組對齊。


圖:位元組對齊