一、DS和[address]
CPU要讀寫一個內存單元的時候,必須先給出這個內存單元的地址,在8086PC中內存地址有段地址和偏移地址組成。DS(數據寄存器)中通常存放要訪問數據的段地址。比如要讀取1000H單元的內容,可以用下面這段代碼:
mov bx,1000H
mov ds,bx
mov al,[0]
注意:由於ds是一個段寄存器,8086CPU不支持將數據直接送入段寄存器的操作。為什么?(這就時8086硬件設計問題了) 所以mov ds 1000H是非法的。只能通過將數據先放到普通寄存器中,然后在放到ds寄存器中。
mov指令可以完成兩種傳送:
1、將數據直接送入寄存器(在8086CPU中,不能講數據直接送入DS中)
2、將一個寄存器中的內容送入另一個寄存器
mov指令訪問內存單元,可以在mov指令中只給出單元的偏移地址,此時,段地址默認在DS寄存器中。
二、CPU提供的棧機制
現在的CPU中都有棧的設計,在基於8086CPU編程的時候,可以將一段內存當做棧來使用。8086CPU提供入棧和出棧指令,最基本的兩個是PUSH和POP。push ax 表示將寄存器ax中的數據送入棧中,pop ax表示從棧頂取出數據送入ax。8086CPU的出入棧操作都是以字節為單位進行的。
CPU如何知道當前棧頂的地址? 這個問題和CPU如何知道當前指令的地址一樣,CS IP存放在當前指定的段地址和偏移地址。SS SP存放當前段地址和偏移地址。
三、棧頂超界問題
8086CPU不保證我們對棧的操作不會超界,它只記錄棧頂的位置,需要開發人員自己操心棧頂超屆問題。
四、段的綜述
我們可以將一段內存定義為一個段,用一個段地址指示段,用便宜地址訪問段內的單元。這完全是我們自己的安排。我們可以有用一個段存放數據,將它定義為“數據段”。用一段存放代碼,將它定義為“代碼段”,用一段當做棧,將它定義為“棧段”。我們可以這樣安排,但是若要讓CPU按照這樣的安排訪問這些段,就要:對於數據段,將它的段地址放到DS中,用mov、add、sub等訪問內存單元的指令時,CPU就將我們定義的數據段中的內容當做數據來訪問。對於代碼段,將它的段地址放在CS中,將段中第一條指令的偏移地址放在IP中,這樣CPU就將執行我們定義的的代碼段中的指令。
可見,不管我們如何安排,CPU將內存中的某段內容當做代碼,是因為CS:IP指向哪里。CPU將某段內存當做棧,是因為SS:SP指向哪里。
