A. 指令和數據都用二進制代碼存放在內存中,從時空觀角度回答CPU如何區分讀出的代碼是指令還是數據。
指令用來確定「做什麼」和「怎樣做」,數據是「做」的時候需要原始數。
計算機可以從時間和空間兩方面來區分指令和數據,在時間上,取指周期從內存中取出的是指令,而執行周期從內存取出或往內存中寫入的是數據,在空間上,從內存中取出指令送控制器,而執行周期從內存從取的數據送運算器、往內存寫入的數據也是來自於運算器。
比如:要計算機做1+2=?中,「+」表示要做什麼和怎樣做,1和2則是做的時候需要的原始數。現在假設某CPU中,「+」用二進制「00000001」來表示,「1、2」分別用「00000001、00000010」來表示。那麼,這段程序存入內存中就是這樣的:
XXXX1:00000001
XXXX2:00000001
XXXX3:00000010 前面的XXXX1 XXXX2
XXXX3表示內存的地址
從上面可以看出,「+」指令和被加數是完全相同的,當然,這是我故意這樣假設的,但是,在實際情況中,這種情況是大量存在的。在正常情況下,CPU只能把XXXX1內存中的00000001作為指令,XXXX2內存中的00000001作為被加數才能得到正確的結果。那麼CPU如何才能做到不把第二個00000001也當成「+」呢?
1.人們把內存的某個地址規定為起始地址(又稱為復位地址),也就是說,當計算機開機或者被強行復位(也就是機箱上那個重啟動按鈕按下的的時候),CPU立即跳轉到這個地址中,並且把它裡面的代碼作為指令來執行,同時根據這個指令的長度和格式判斷下一條指令在什麼地方。
對於X86系列CPU(也就是現在人們常用的什麼奔XX、賽XX系列),它的復位地址是FFFF0,如果表示成邏輯地址則是:FFFF:0000。對DEBUG比較熟悉的朋友或者會在一些高級語言中嵌入匯編語言的朋友可以這樣做一個試驗:
用DEBUG執行一條指令(這是一條無條件跳轉指令):jmp
FFFF:0000,或者在高級語言中嵌入這條匯編指令,執行後,你就會發現,計算機重新啟動了。其實,用程序控制計算機重啟的最本質的操作就是這樣的。
2.給各種指令規定了相應的長度和格式。比如:某數+某數這條指令就規定:這條指令的長度是3個位元組,其中第一個位元組表示「+」,後面兩個位元組表示被加數和加數。於是,當CPU到達這個指令後,就自動把第一個代碼作為指令,後面兩個代碼作為數據,依次類推,第4個代碼就必然是指令.....
B. 指令和數據均存放在內存中,計算機如何從時間和空間上區分它們是指令還是數據
1.數據區分兩種,一種是 棧數據,和堆數據。
2.而全局變數和靜態變數和常量字元串放在文本區或者叫全局區,
3.並在文本區的隔壁還有一個是指令區,專門放指令
他們分別有一個段基址寄存器指向他們的。所以怎麼之別是不需要你來關心的,是由操作系統和進程tcb塊來管理。