CPU Segments
1.Introduction
8086CPU在訪問內存時要由相關部件提供內存單元的段地址和偏移地址,送入地址加法器合成物理地址。段地址在8086CPU的段寄存器中存放,8086CPU有4個段寄存器:CS,DS,SS,ES。
CS為Code Segment,代碼段寄存器,結合指令指針寄存器IP(Instruction Pointer)來確定要執行的下一條指令的內存地址;
DS為Data Segment,數據段寄存器;
SS為Stack Segment,棧段寄存器;
ES為Extra Segment,附加寄存器;
我們可以將一段內存定義為一個段,用一個段地址指示段,用偏移地址來訪問段內的單元,這完全是我們自己來安排。我們可以設定一個段存放數據,將它定義為DS;設定一個段存放代碼,將它定義為CS;設定一個段當作棧,將它定義為SS。
對于數據段,將它的地址放在DS寄存器中,用mov, add, sub等訪問內存單元時,CPU就將我們定義的數據段中的內容當作數據來訪問;
對于代碼段,將它的地址放在CS寄存器中,將段第一條指令的偏移地址放在IP中,這樣CPU就將執行我們定義的代碼段中的指令;
對于棧段,將它的段地址放在SS寄存器中,將棧頂單元的偏移地址放在SP中,這樣CPU在需要進行棧操作時,比如執行push, pop指令,就將我們定義的棧段當作棧空間來使用。
2. Data Segment
通過DS寄存器,可以設置任意內存中的數據。
mov ds,ax
mov ax,1123
mov [0],ax
由上圖可知,可以通過數據段寄存器DS來設置內存中的數據。
3. Stack Segment
現在的CPU中都有棧的設計,8086CPU也不例外。8086CPU提供相關的指令來以棧的方式訪問內存空間。這意味著,在基于8086CPU編程時,可以將一段內存當作棧來使用,并提供了入棧和出棧的指令push, pop。那么問題來了,如何任性地指定哪段內存作為棧來使用呢?8086CPU中提供了兩個寄存器SS和SP來完成這項任務。棧頂的段地址存放在段寄存器SS中,偏移地址存放在SP中。這個用法和CS:IP的用法是一樣的。
mov ss,ax
mov ds,ax
mov ax,10
mov sp,ax
push ax
將上述代碼通過A命令,輸入到Debug程序中。
通過命令T來執行上述代碼。
通過兩次push,將1000:000E處和1000:000C處的值設置成了ax中的值。字在內存中存儲時,要用兩個地址連續的內存單元來存放,字的低字節存放在低地址單元,高位字節存放在高地址單元。通過上圖可以看出入棧push時,棧頂指針SP寄存器是在減少的,每次減少了一個字,即兩個字節。出棧的過程SP的過程正好相反,是在增加的。
從上面的例子還可以看出,同一段內存空間,即可以用來當作數據段,也可以用來當作棧來使用。