我正在開發嵌入式系統項目。我的目標是32位(32位地址總線)。如何知道編譯器是否執行內存對齊?
我需要知道編譯器是否執行內存對齊。
換句話說,如果我聲明瞭以下變量:
uint16_t x = 0xFFFF;
x
將被保存在一個特定條目類似:
Address 0x00000000 -> FFFF0000
或者可以將它保存這樣的:
Address 0x00000000 -> 000000FF
Address 0x00000001 -> FF000000
我正在開發嵌入式系統項目。我的目標是32位(32位地址總線)。如何知道編譯器是否執行內存對齊?
我需要知道編譯器是否執行內存對齊。
換句話說,如果我聲明瞭以下變量:
uint16_t x = 0xFFFF;
x
將被保存在一個特定條目類似:
Address 0x00000000 -> FFFF0000
或者可以將它保存這樣的:
Address 0x00000000 -> 000000FF
Address 0x00000001 -> FF000000
當然,你的編譯器總是會做出明智的選擇e目標架構。
通常,它會將數據類型與該數據類型的「自然」地址對齊。這不會錯誤地對齊變量,以便訪問它會導致一些錯誤或具有災難性的性能。
對於你的特殊情況,如果x
是一個局部變量,它可能會在一個寄存器或堆棧中,而不是一個事先已知的絕對地址。大多數平臺都有堆棧對齊的規則可能會發揮作用(即當進入某個函數時,堆棧可能始終與某些2的冪對齊)。如果它不是本地自動的,則上述內容將適用,即編譯器將以自然和「良好」的方式對齊變量。
如果x是一個靜態或全局的? –
如果x是靜態的或全局的(全局無論如何都是靜態的)取決於你聲明它的方式和位置! –
無論是在'.data' /''.bss'還是在堆棧中分配,編譯器仍然需要做相同的基本對齊考慮。這個答案的意思是,除此之外還有其他一些考慮因素,具體取決於堆棧的處理方式([有關堆棧處理的更多信息](http://en.wikipedia.org/wiki/Call_stack))。 – Lundin
可能是一個簡單的方法來檢查:
uint8_t *pChar;
uint16_t x = 0xFF;
(uint8_t *)pChar = (uint8_t *)&x;
,然後打印:
*pChar
和*(pChar + 1)
這也有利於檢查Endian的模式下,CPU英寸
如果您使用GCC編譯器(可能作爲交叉編譯器定位您的系統),您可以使用__alignof__
keyword(它是GCC擴展)。您可能還需要使用packed
variable attribute
由於Lundin明智評論,最新C11標準給你_Alignof
關鍵字和_Alignas
符。
因此,值得使用最近的編譯器。
或者只是使用C11編譯器(例如GCC 4.9.x),然後使用標準的'_Alignof'關鍵字。 – Lundin
我只相信編譯器完成其工作...否則我想你可以做一些「hackish的」東西發現:
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
int main()
{
uint16_t x = 0xFFFF;
uintptr_t align = (uintptr_t)&x % sizeof(uint16_t);
if(align != 0) // aint gonna happen
{
printf("Scandal! Variable incorrectly aligned!\n");
}
align = (uintptr_t)&x % sizeof(uintptr_t);
if(align != 0) // might very well happen, not an issue
{
printf("Variable not aligned at an address which is a multiple of the CPU alignment\n");
printf("At address %p, \"optimal\" %p", &x, (uint8_t*)&x - (uint8_t*)align);
}
return 0;
}
如果使用的是C11,你可以強制編譯器使用不同的對齊方式。如果上面的代碼更改爲
_Alignas(uintptr_t) uint16_t x = 0xFFFF;
那麼你不應該得到任何印刷,因爲它強制在同一對準被分配爲是地址總線寬度的變量。爲什麼你想這樣做,我不知道,因爲編譯器知道如何做比這些程序員更好的事情。
1.它會給你什麼? 2.試着去看看你是否有這種感覺,如果你是全部定下來的話。 – Eregrith
閱讀編譯器的手冊。通常,編譯器提供了在靜態分配的變量上指定顯式對齊控制的方法,如'#pragma DATA_ALIGN'。 – user3528438
此外,如果您正在進行微控制器編程,您通常會擁有一個「映射文件」的好處,它可以完全顯示如何分配所有內容以及在什麼地址。 – Lundin