在嵌入式C語言中使用結構的方法有哪些
在嵌入式C語言中該如何使用結構,嵌入式為何一定要使用C語言呢?在嵌入式C語言中使用結構的方法有哪些呢?
我們通常將記憶體設想為單位元組儲存位置的集合。每個位置都有一個唯一的地址,允許我們訪問該地址的資料。但是,處理器通常以大於一個位元組的塊形式訪問記憶體。例如,處理器可以以四位元組塊的形式訪問記憶體。
文章來源:電子發燒友
你可能想知道這兩種處理記憶體的方式之間有什麼區別。處理器一次讀取一個位元組並向記憶體寫入。請注意,在讀取記憶體位置或寫入記憶體之前,我們需要訪問該記憶體單元,並且每次記憶體訪問都需要一些時間。假設我們想要讀取圖1中儲存器的前八個位元組。對於每個位元組,處理器需要訪問記憶體並讀取它。因此,為了讀取前八個位元組的內容,處理器將必須訪問記憶體八次。
處理器一次讀取4個位元組並將其寫入記憶體。因此,為了讀取前四個位元組,處理器訪問儲存器的地址0並讀取四個連續的儲存位置(地址0到3)。同樣,要讀取下一個四位元組塊,處理器需要再次訪問記憶體。它轉到地址4並同時從地址4到7讀取儲存位置。
對於位元組大小的塊,需要8次記憶體訪問來讀取連續8個位元組的記憶體。只需要兩次記憶體訪問。如上所述,每次記憶體訪問都需要一些時間。儲存器配置減少了訪問次數,因此可以提高處理效率。處理器在訪問記憶體時使用的資料大小稱為記憶體訪問粒度。
硬體設計人員經常採用另一種重要技術來提高處理系統的效率:它們限制處理器,使其只能在某些邊界訪問記憶體,處理器可能僅能夠在四位元組邊界上。
這種邊界限制會使系統顯著提高效率嗎?仔細看看。假設我們需要讀取地址為3和4的記憶體位置的內容。如果處理器可以從任意地址開始讀取一個四位元組的塊,那麼我們可以訪問地址3並透過單個記憶體訪問讀取兩個所需的記憶體位置。但是,如上所述,處理器不能直接訪問任意地址;相反,它只在某些邊界訪問記憶體。那麼如果處理器只能訪問四位元組邊界,它將如何讀取地址3和4的內容?
由於記憶體訪問邊界限制,處理器必須訪問地址為0的記憶體位置並讀取連續的四個位元組(地址0到3)。接下來,它必須使用移位操作將地址3的內容與其他三個位元組(地址0到2)分開。類似地,處理器可以訪問地址4並從地址4到7讀取另一個四位元組塊。最後,可以使用移位操作將所需位元組(藍色矩形)與其他三個位元組分開。
如果沒有記憶體訪問邊界限制,可以用一個記憶體訪問讀取地址3和地址4。但是,邊界限制迫使處理器兩次訪問儲存器。那麼,如果資料操作變得更加困難,為什麼需要限制對某些邊界的記憶體訪問呢?記憶體訪問邊界存在限制,因為對地址進行某些假設可以簡化硬體設計。例如,假設一個記憶體塊中的所有位元組都需要32位來定址。如果將地址限制為四位元組邊界,那麼32位地址中的兩個最低有效位將始終為零(因為地址始終可以被4整除)。因此,我們可以使用30位來定址一個232位元組的記憶體。
例如,考慮一個具有四位元組記憶體訪問粒度的處理器,它只能以四位元組邊界訪問記憶體。假設一個四位元組變數儲存在地址1,在這種情況下,我們需要兩次記憶體訪問和一些額外的工作來讀取未對齊的四位元組資料(“未對齊”指它被分成兩個四位元組塊)。
但是,如果將一個四位元組變數儲存在4的倍數的任何地址,只需要一個記憶體訪問來修改資料或讀取資料。所以將K位元組資料型別儲存在K的倍數的地址可以提高系統的效率。因此,C語言“char” 變數(只需要一個位元組)可以儲存在任何位元組地址,但是一個雙位元組變數必須儲存在偶數地址中。
四位元組型別必須從可被4整除的地址開始,並且八位元組資料型別必須儲存在可被8整除的地址。例如,假設在特定機器上,“short”變數需要兩個位元組,“int ”和“float” 型別佔用四個位元組,“long ”、“double”指標佔用八個位元組。這些資料型別中的每一種通常應具有K的倍數的地址,其中K由下表給出。
請注意,不同資料型別的大小可能因編譯器和計算機體系結構的不同而不同。sizeof()運算子是查詢資料型別實際大小的最佳方法。
我們知道將分配四個記憶體位置來儲存結構中的成員,並且記憶體位置的順序將與宣告成員的順序相匹配。第一個成員是一個單位元組變數,可以儲存在任何地址。因此,第一個可用儲存位置將分配給此變數。編譯器為此變數分配地址0。下一個成員是一個四位元組資料型別,只能儲存在4的倍數地址。第一個可用的儲存位置是地址4。但是,這需要不使用地址1、2和3。如你所見,資料對齊要求會導致記憶體佈局中出現一些浪費空間(或填充)。
下一個成員是e,它是一個單位元組變數。第一個可用的儲存位置分配給此變數。接下來,我們到達f,這是一個雙位元組變數。它可以儲存在可被2整除的地址。第一個可用空間是地址10。如你所見,為了滿足資料對齊要求,將出現更多的填充。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69940009/viewspace-2650267/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 嵌入式C語言中的組成結構是什麼C語言
- C語言中結構體感悟C語言結構體
- c語言中的三種迴圈語句結構C語言
- go語言中遍歷陣列的方法有哪些Go陣列
- C語言中結構體直接賦值?C語言結構體賦值
- Go 語言中 defer 使用時有哪些陷阱?Go
- 在Go語言中,怎樣使用Json的方法?GoJSON
- static在C語言中的作用C語言
- C語言中結構體struct的對齊問題C語言結構體Struct
- C語言中的關鍵字有哪些,分別代表什麼意思C語言
- "->" 在c語言中是什麼意思?C語言
- C語言中編譯和連結C語言編譯
- 淺談C語言中函式的使用C語言函式
- C語言中的#和##C語言
- C語言中水平製表符 與退格鍵 的使用方法探索C語言
- Go 語言中的方法Go
- c語言中計算陣列長度的方法C語言陣列
- python語言中基本資料型別有哪些?Python資料型別
- C語言中關鍵字typedef、enum的使用C語言
- 解析C語言中的sizeofC語言
- C語言中extern的用法C語言
- c語言中的作用域C語言
- 【C】 30_C語言中的字串C語言字串
- async/await 在 C# 語言中是如何工作的?(下)AIC#
- async/await 在 C# 語言中是如何工作的?(中)AIC#
- async/await 在 C# 語言中是如何工作的?(上)AIC#
- C語言中的複雜資料型別,你掌握了哪些?C語言資料型別
- c語言中的getchar()和EOFC語言
- C 語言中的 sscanf 詳解
- C 語言中的 time 函式函式
- Flowmatic:Go語言中結構化併發庫Go
- 在C語言中實現泛型程式設計C語言泛型程式設計
- 乾貨好文帶你理解C語言中的連結串列C語言
- C語言中四捨五入問題總結C語言
- c語言中,while(1)語句使用break語句跳出迴圈C語言While
- Go 語言中的 collect 使用Go
- 在 Go 語言中,我為什麼使用介面Go
- C語言中qsort函式的用法C語言函式