本記錄藉由 md (memory display) 來探討 volatile 以及 pointer 間接取值
我們在使用md時,實際上是呼叫do_mem_md函式。
在 do_mem_md 函式中 有三個case最後都會call print_buffer(... 秀出資料
1. print_buffer(addr, p, size, linebytes/size, DISP_LINE_LEN/size);
2. print_buffer(addr, linebuf, size, linebytes/size, DISP_LINE_LEN/size);
3. print_buffer(addr, (void*)addr, size, length, DISP_LINE_LEN/size);
這裡以case 3 來作探討: 要印的資料就是addr的內容,在此只說明如何印出一筆資料。
先來看看print_buffer的宣告
int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen);
就是因為函式的data參數型態為void*,因此須要先將addr轉換為void*的型態。
在print_buffer中和data相關的說明擷取如下
uint32_t x;
/* Copy from memory into linebuf and print hex values */
x = lb.ui[i] = *(volatile uint32_t *)data;
printf(" %0*x", width * 2, x);
由於傳入的實際上是記憶體中的位址addr,而要印的資料型態為uint32_t,因此要先做轉型 (uint32_t *) 至於volatile 稍後會說明。 再藉由間接取值的方式將記憶體內容assign給 x 作輸出。
再來說明volatile,網路上已經很多優秀的說明,這邊列出我覺得不錯的一個連結
http://blog.csdn.net/c_bg44/article/details/1538235
用volatile 的變數每次被呼叫使用時,會從ram中取值。
而沒有使用volatile的變數有可能從cpu register中取值,這是因為此變數之前有被呼叫使用過。(編譯器優化程式碼的結果,因為從cpu register取值比ram快多了)
因此若想要確保每次的取值都是乖乖從ram拿出來就要加上volatile。
沒有留言:
張貼留言