1. 程式人生 > >跟我學匯編(三)寄存器和物理地址的形成

跟我學匯編(三)寄存器和物理地址的形成

註意 con 什麽 size 單獨 既然 cpu 個數 ng-

一、通用寄存器

對於一個匯編程序猿來說,CPU中主要部件是寄存器。寄存器是CPU中程序猿能夠用指令讀寫的部件。程序猿通過改變各種寄存器的內容來實現對CPU的控制。

不同的CPU,寄存器的個數、結構是不同的。8086CPU 有14個寄存器。每一個寄存器有一個名稱。

這些寄存器是:AX、BX、CX、DX、SI、BP、IP、CS、SS、DS、ES、PSW。在今後的學習中我們用到這些寄存器時就對這些寄存器進行介紹。

AX、BX、CX、DX四個寄存器能夠存放一般性的數據,所以這四個寄存器稱為通用寄存器。在8086CPU中,寄存器都是16位的,能夠存放兩個字節的數據,所以表示的最大值是2^16-1。

8086CPU的上一代CPU使用的是8位的寄存器,所以為了保證程序的兼容性,使的針對上一代CPU開發的匯編程序能夠在8086CPU上運行。8086將通用寄存器分成兩個8位的寄存器:

  • AX能夠分為AH和AL
  • BX能夠分為BH和BL
  • CX能夠分為CH和CL
  • DX能夠分為DH和DL

    技術分享

以AX為例。如上圖所看到的。AX的0~7位為AL,8~15位為AH。對AX中存放的數據有兩種解釋方式。假設是看做16位的AX則表示20000,假設看做8位的寄存器,則AH表示78,AL表示32。

二、幾條匯編指令

以下我們來看一下匯編中兩個最經常使用的指令mov和add,下表展示了它們的使用方法。

技術分享

註意:匯編指令是不區分大寫和小寫的,所以寫成ADD AX,8和add ax。8的效果是一樣的。

我們結合著剛剛講過的寄存器來看一下匯編指令是怎樣改變寄存器中的內容的。

我們假定開始時,AX和BX中的數據都是0000H。

技術分享

如今我們來分析一下最後的?是怎麽回事。最後一條指令運行之前AX=8226H,BX=8226H,假設運行ADD操作。則A的值應該是1044CH,可是AX是16位的寄存器。最大值就為FFFFH,所以超出16位的部分就會被省略,所以AX=044CH。

再來看看對AH和AL的操作實例:

我們還是假設,開始時AX和BX中的數據為0000H。

技術分享

以下來看一下最後的?應該是什麽值,ADD AL,93H運行後AL的數值為158H。可是AL為8位寄存器最大僅僅能存儲FFH。所以超過8位的部分會自己主動省略,於是AX中數據就變成了0058H。

三、物理地址的形成

8086CPU是16位的結構,這就意味著字長是16位,寄存器的最大寬度為16位,運算器一次能夠處理16位的數據。寄存器和運算器之間的數據通路為16位。

然而8086CPU卻有20位地址總線。能夠傳送20位地址,所以能夠達到1MB的尋址空間。可是由於是16位架構的CPU,所以假設僅僅從CPU內部簡單的將地址送出則僅僅能形成16位的地址,尋址能力也僅僅有64KB。這可咋辦呢。

為了解決上述問題,8086CPU採用了一種使用兩個16位地址合成一個20位地址的方法來形成一個20位的物理地址,從而擴大了尋址能力。

物理地址=段地址*16+偏移地址

技術分享

地址加法器採用物理地址=段地址*16+偏移地址的方法用段地址和偏移地址合成物理地址。比如,8086CPU想要訪問123C8H的內存單元,此時。加法器就利用1230H和00C8H兩個地址形成123C8H這個地址。

我們能夠用一個簡單的樣例來描寫敘述一下這個思想,例如以下圖所看到的,假如學校、體育館和圖書館的位置例如以下:

技術分享

假如你有一張能夠寫4位數的紙條,那麽圖書館的位置能夠被表述為2826,假設不幸你沒有4位的紙條僅僅有兩張三位的紙條,那麽圖書館的位置就必須借助上面的思想,我們能夠用200和826兩個三位數字來表示,圖書館的位置就在200*10+826=2826m上。

四、段寄存器

上面我們一直說段地址,但實際上內存中並沒有分段,段的劃分來自CPU,由於8086CPU用基礎地址(段地址)*16+偏移地址=物理地址的方式給出內存的物理地址,使得我們能夠用分段的方式來管理內存。

我們能夠覺得10000H~100FFH的內存單元為一個段,段的起始地址是10000H,段地址為1000H,大小為100H;我們也能夠覺得10000H~1007FH、10080H~100FFH的內存單元組成兩個段,它們的起始地址為10000H和10080H,段地址為1000H和1008H。段大小為80H。

既然地址加法部件要用段地址和偏移地址形成物理地址。那麽這兩個地址就必須都被保存下來。8086CPU有四個段寄存器:CS、DS、SS、ES。

CS和IP是8086CPU中兩個關鍵的寄存器,他們指示了CPU當前要讀取指令的地址。CS為代碼段寄存器,IP為指令指針寄存器。

假設CS中的內容為M,IP中的內容為N。那麽CPU就將從內存M*16+N單元開始,讀取一條指令並運行。也能夠表述為例如以下:

8086機中,隨意時刻,CPU將CS:IP指向的內容當做指令運行。

以下通過一組圖的方式展示8086CPU讀取、運行一條指令的過程。

技術分享

初始狀態。CS:2000H,IP:0000H。

技術分享

地址加法器利用CS和IP中的地址形成物理地址。

技術分享

地址加法器將物理地址送入輸入輸出控制電路。

技術分享

輸入輸出電路將地址送上地址總線。

技術分享

從內存20000H單元開始存放的機器指令B8 23 01通過數據總線被送入CPU

技術分享

輸入輸出電路將機器指令送入指令緩沖器。

技術分享

讀取一條指令後。IP中值會自己主動添加,以使CPU能夠讀取下一條指令,由於當前讀入的指令為3個字節,所以IP的值加3。

技術分享

運行控制器運行指令。

技術分享

AX中的內容被改變。

後面的過程與這個過程是同樣的,這裏不再畫出來了。由於文章的篇幅已經非常長了。

註意:在8086CPU加電啟動後或復位後,CS和IP被設置為CS=FFFFH,IP=00000H,即8086CPU在剛啟動時,CPU從內存FFFF0H單元中讀取指令運行。

五、改動CS、IP的指令

那麽我們能否夠通過指令改變CS和IP的值呢?答案是肯定的,可是不是通過MOV指令。8086提供了單獨的指令來改變這兩個寄存器的值。

1、若想同一時候改變CS和IP的值,能夠用“JMP 段地址:偏移地址”的指令來完畢。

比如:JMP 2AE3:3,運行後:CS=2AE3H。IP=0003H。CPU將從2AE33H單元讀取指令。

2、若想僅改動IP的內容,能夠使用形如“JMP 某個合法寄存器”的指令來完畢。

比如:JMP AX,指令運行前:AX=1000H,CS=2000H。IP=00003H,指令運行後:AX=1000H,CS=20000H,IP=1000H

跟我學匯編(三)寄存器和物理地址的形成