2016-08-23 57 views
2

8086使用16位指令,但RAM地址只保存8位CPU如何從RAM加載程序?它是否加載一個地址,然後檢查指令是否需要1/2/3個字節(例如,將一個立即移動到一個8/16位寄存器),然後執行操作,或者我錯誤地認爲一個RAM'空間'是16位大?從8086的RAM中加載程序

+0

RAM實際上是24位。這就是爲什麼它的段落與段寄存器加偏移量對齊。當你指定一個8位地址時,它假定段寄存器是基址。 –

回答

5

許多指令是多字節的,是的,這意味着它們跨越兩個或更多的地址。

IIRC,8086的存儲器總線是16位,所以它可以在一次操作中加載16位(兩個相鄰的地址)。您將字節可尋址內存與總線寬度相混淆。

它加載一個地址,然後如果所述指令需要1/2/3字節檢查(例如移動即時到寄存器8/16位)

它不斷地取指令字節到6字節緩衝區(一次2個字節,因爲它是一個16位CPU,帶有16位總線)。該緩衝區足夠大以容納最大允許的8086指令(不包括可能被單獨解碼的前綴IDK)。當它完成前面的指令時,它會查看緩衝區。請參閱下面的鏈接以獲得更好的描述,但它可能會嘗試將緩衝區解碼爲整個指令。如果它在找到指令結束之前碰到提取緩衝區的末尾,它會等到下一個提取循環完成並再次嘗試。

另請參閱:8086 CPU architecture,這是「8086代碼獲取」的第一個命中。它確認提取和執行確實重疊,所以它以最基本的方式流水線化

TL:DR:它獲取到一個緩衝區,直到它有一個完整的指令解碼。然後它將任何額外的字節移到緩衝區的前面,因爲它們是下一條指令的一部分。

我讀過,通常指令取指是8086的瓶頸,因此對代碼大小的優化幾乎勝過其他任何東西。


流水線CPU不需要等待執行前面的指令就可以開始解碼。現代CPU也有更高帶寬的代碼獲取,因此他們有一個解碼指令隊列準備就緒(除了當分支搞砸了。)請參閱http://agner.org/optimize/以及標記wiki中的其他鏈接。


此外,一些非常常見的指令是單字節,如push r16

+2

我想我們可以進入我最愛的解碼雜草[** The Assembly of Sect 3.3.7 **](https://courses.engr.illinois.edu/ece390/books/artofasm/CH03 /CH03-3.html#HEADING3-102)。這是解碼的概述。 –

+0

非常感謝您的快速回復。 –

+2

8086上的預取隊列只有6個字節,而指令長度沒有限制。您可以使用盡可能多的冗餘前綴,15個字節的限制與'386一起添加。沒有冗餘前綴,指令可能會超過6個字節。例如'mov [es:0],1234'長度爲7個字節。但是,根本沒有前綴,我不認爲8086指令可以超過6個字節。我的猜測是前綴字節被單獨解碼,並且單獨地像他們自己的指令一樣。 –