這個問題隸屬於CPU設計的范疇
其等價問題為 CPU是如何獲取指令和數據的,進一步的,指令和數據是否是分開存取的
普遍的說法是這樣的,如果指令和數據分開存取,則是哈佛結構,否則是馮諾依曼結構
不要嘗試去記憶這些結論,我們要去思考,去理解這個事情
以51內核的單片機為例,我們將編譯后的bin文件燒錄到片子里面,然后上電之后程序執行
看似簡單的過程,里面也有一些我們不是很清楚的細節,一些記憶碎片沒有完全聯系起來
比如:
a.51單片機的norflash 有幾十K
b.我們燒錄進去的代碼肯定包含指令和數據
c. 51 單片機的運行也是需要ram的,好像叫做sram
這個時候,問題逐漸變得清晰起來,我至少有以下幾個問題要問:
1. 燒錄的代碼全部燒到norflash了嗎,還是指令在flash, 數據在sram?
2. sram能掉電存儲嗎?
3. int main() { int a = 5; int b = 10; int c = a + b; return c; } 這個例子中,5, 10是指令還是數據?
4. int main() { printf("helloworld\n"); return 0; } 這個例子中,"helloworld"是指令還是數據?
========================================================================
不問不知道,我在這么基礎的問題上竟然還犯了錯誤:
首先,我的大前提中的b就犯了錯誤,燒錄的code全是指令
其次,常識性的錯誤:sram不可掉電存儲,代碼全部燒到norflash中
所謂的數據是指運行時的概念,CPU run起來的時候會去訪問ram, 通過尋址指令在cpu寄存器和ram中來回搬運數據
MOV R1,#00H的機器代碼是 A8 00,一共兩個字節,而且存儲在ROM。
而你把MOV R1,#00H認為是兩個部分是錯誤的,這是一個完整的指令(即存儲在ROM),
不是說MOV是指令而后面的R1,#00H不是指令——你只是看表面上的內容,沒有看其本質。
一條匯編指令的完整格式是[標號:]操作碼[源操作數],[母的操作數][;注釋],其中中括號內的可以省略
也就是說,問題3,4中的常量也是code的一部分, 只不過,涉及全局變量和常量字符串的code可能在鏈接腳本的處理上有點特殊
關於鏈接腳本,需要再開一個專欄講解
回答了這些問題,單片機上電啟動的圖景才漸漸在腦海中清晰起來。
單片機上電后,CPU去norflash中的固定位置取第一條指令,然后譯指執行,這個期間,一些存儲計算等操作會用到ram, 那就必然涉及CPU訪問ram。下圖是51的系統結構框圖
那這到底是不是哈佛結構呢?
看兩點:一是程序和數據存儲要分開,二是程序和數據要有單獨的讀取路徑
很遺憾,51不滿足第二點,它是公用了數據線 和地址線去訪問指令和數據的
那誰是標准的哈佛結構呢,我們接觸過的cortex-m3的單片機就是。
所以其實,后面會發現,現代的CPU都是混用這兩種結構了,CPU和存儲器並不直接相連,在cache外面,程序和數據是存在一起的
通過AHB總線訪問,到了里面又會分開,指令是指令,數據是數據。