2014-06-23 30 views
0

我對使用c風格指針訪問特定地址有點困惑。尋址指針的不同方式C/C++

我有一個32位芯片,我試着編程。我需要翻轉一些內容或任何內存。以下解決方案正常工作。

uint32 strbase = 0x00168380; 
volatile uint32 *ram = (uint32*)0x03000000; 


ram[(strbase+0x48)/4] = 0x10000000; 
ram[(strbase+0x4c)/4] = 0x10000000; 
ram[(strbase+0x50)/4] = 0x10000000; 
ram[(strbase+0x54)/4] = 0x10000000; 
ram[(strbase+0x58)/4] = 0x10000000; 
ram[(strbase+0x5c)/4] = 0x10000000; 
ram += (strbase+0x60)/4; 

但是,我有點困惑。我試着寫了幾個不同的子程序,我認爲它們是等效的,但沒有奏效。以下方法只是有點作品。

uint32 strbase = 0x00168380; 
volatile uint32 *ram = (uint32*)0x03000000; 

*(uint32*)(0x03000000 + 0x001683c8) = 0x10000000; 
*(uint32*)(0x03000000 + 0x001683CC) = 0x10000000; 
*(uint32*)(0x03000000 + 0x001683D0) = 0x10000000; 
*(uint32*)(0x03000000 + 0x001683D4) = 0x10000000; 
*(uint32*)(0x03000000 + 0x001683D8) = 0x10000000; 
*(uint32*)(0x03000000 + 0x001683DC) = 0x10000000; 
ram += (strbase+0x60)/4; 

以下方法根本不起作用。

uint32 strbase = 0x00168380; 
volatile uint32 *ram = (uint32*)0x03000000; 

ram += strbase+0x48; 
*ram++ = 0x10000000; 
*ram++ = 0x10000000; 
*ram++ = 0x10000000; 
*ram++ = 0x10000000; 
*ram++ = 0x10000000; 
*ram++ = 0x10000000; 

我一直在這個燉一段時間。我認爲這可能是編譯器做了一些有點優化。希望你們中的一個能夠向我解釋什麼是錯誤的,或者指出我需要哪些資源來解決這個問題。

+1

在你的第三個示例中,值'(strbase + 0x48)'需要除以四。 – rwong

+0

在中間示例中,如果不將地址強制轉換爲uint32_t *,編譯器將生成警告。這是你「有點作品」的意思嗎? – sansuiso

+0

uint32是我製作的typedef。我所擁有的是編譯器和我的代碼。 –

回答

1

在第二溶液中,你typedefing到

(uint32*) 

代替

(volatile uint32*) 

這使得編譯器優化存儲器存取並重新排列寫入。如果此代碼是更大程序的一部分,並且硬件期望您按順序寫入,則可能是此問題。

在第三解決方案,因爲布朗博士已經說過,你有4分頻得到:

ram += (strbase+0x48)/4; 

注意,一般來說,你應該經常使用的,而不是常量使用sizeof(UINT32)。它有助於可讀性和C標準不提供完整的整數類型的大小。

+0

'sizeof(uint32)'是一種矯枉過正。如果'uint32'和'uint32_t'相同,它就有32位;只有在使用16位或32位字節時,它的「sizeof」纔可以與4不同。雖然這在理論上是可行的,但您正在編寫特定的嵌入式平臺,並且您不需要假裝代碼以任何方式可移植。 – anatolyg

+0

@anatolyg啊我現在看到 - POSIX指定uint32_t的確切位寬。我的錯。 反正,使用sizeof(variable_name)有助於可讀性,並應在可能時予以優先考慮。 –