1. 程式人生 > >16-8086處理器的定址方式

16-8086處理器的定址方式

CPU作為計算機的中央處理器,每天忙忙碌碌,只要它工作著就會不斷地執行指令,處理各種資料。既然要處理資料,就會涉及兩個問題:

1. 資料在哪裡,如何獲取

2. 處理完之後,把資料送到哪裡去

而在計算機中,定址方式就是如何找到要操作的資料,以及把資料處理完存放到哪裡。對於8086處理器來說,它的定址方式大致分為這幾類:暫存器定址,立即定址,記憶體定址,下面我們分別來討論這幾種定址方式。

 

1. 暫存器定址

暫存器定址就是指令執行時,需要操作的資料位於暫存器中,比如下面幾條指令:

mov ax,cx
add bx,0xf000
inc dx

在第一條指令中,有兩個運算元都是暫存器,ax表示目的運算元,cx表示源運算元,這是典型的暫存器定址。

第二條指令中,目的運算元bx是一個暫存器,因此這條指令也是暫存器定址。

第三條指令就更不用說了,dx作為一個暫存器,既是源運算元,也是目的運算元

 

2. 立即定址

立即定址又叫立即數定址,也就是說,指令的運算元是一個立即數,比如:

add bx,0xf000

在第一條指令中,目的運算元bx是一個暫存器,採用了暫存器定址方式;而0xf000是源運算元,這是一個直接給出的數值,並且這個資料就在指令中直接得到,不需要通過其他方式尋找,故稱為立即數,這也是一種定址方式,叫做立即定址。

mark:
mov ax,mark

再來看這條指令,目的運算元ax也採用了暫存器定址方式,而源運算元是一個標號,通過前面的學習我們知道偽彙編指令需要轉換成純彙編指令,因為真正編譯後,標號mark也會被轉化成一個立即數

,因為該指令的源運算元也採用了立即定址方式。

 

 

另外,我們在確定一條指令的定址方式時,是根據運算元來看的,例如有的指令只有一個運算元,比如inc ax指令,那麼我們能確定這條指令就是採用暫存器定址方式的。但是對於add bx,0xf000指令來說,這條指令既採用了暫存器定址方式,也採用了立即數定址方式,所以對於有兩個運算元的指令來說,需要根據目的運算元或者源運算元來確定定址方式。

 

3. 記憶體定址

暫存器定址的運算元位於暫存器中,立即定址的運算元位於指令中,是指令的一部分。這也是速度最快的兩種定址方式。但是,它們也有一些侷限性,因為有時候我們並不知道要操作的數是多少,再說了,暫存器的數量有限。因此,考慮到記憶體的容量大,在指令中使用記憶體地址來操作記憶體中的資料是再好不過的了。

我們知道8086CPU處理器訪問記憶體時,採用是的段地址和偏移地址合成20位實體地址的模式。 段地址是由8086的4個段暫存器(ES、DS、CS、SS)來指定的,偏移地址由指令來指定。因此,所謂的記憶體定址其實就是在尋找偏移地址。

 

3.1直接定址

直接定址方式使用了一個偏移地址,我們通過以下幾條指令來說明。

第一條指令如下:

mov ax,word [ds:0x5c0f]

要表示記憶體地址,必須使用中括號括起來。

在上述指令,源運算元是直接定址方式,當這條指令執行時,處理器將段暫存器ds的內容左移4位,加上0x5c0f,形成20位的實體地址。接下來,從該實體地址處取得一個字長度的資料,傳送到暫存器AX中。

 

第二條指令如下:

add word [ds:0x0230],0x5000

第二條指令,目的運算元採用的直接定址方式。當這條指令執行時,處理器用同樣的方法,計算出20位記憶體地址,並且把0x0230這個資料用1個字的長度放進去。

 

第三條指令如下:

Mark:
xor byte [es:Mark],0x05

第三條指令中,目的運算元雖然使用了標號,但標號屬於偽指令,轉換成純指令,標號就會成為一個確定的數字,所以依然屬於直接定址。

通過以上幾條指令我們可以知道:在8086中,訪問記憶體的時候,如果是段暫存器加一個固定偏移量(常量),就是直接定址。

 

 

3.2 基址定址

先從字面上來分析一下“基址定址”,基址的意思是“基礎地址”,所謂基址定址就是在指令的地址部分使用基址暫存器bx或bp來提供偏移地址,同時還可以指定一個偏移量(可正可負)。

很多時候,我們有一大堆資料要處理,而且它們通常都挨在一起,順序存放。比如:

Data:
dw 0x0020,0x0100,0x000f,0x0300,0xff00

假如要把這些資料統統加一,那麼使用直接地址的話,如下:

Code:
inc word[ds:Data+0]
inc word[ds:Data+2]
inc word[ds:Data+4]
. . . . . .

我們知道這種方式是使用的直接定址方式,雖然也能實現,但考慮效率和程式碼的簡潔性,我們用迴圈來完成更好,因此可以使用基址定址,如下:

mov bx,Data
mov cx,5 

IncreaseOne:
inc word[ds:bx]	;bx就是基礎地址,當然你也可以使用bp暫存器
add bx,2
loop IncreaseOne

在8086處理器中,訪問記憶體的時候,也就是中括號裡面,一般基址定址經常使用bx暫存器和bp暫存器,通常bx是針對資料段操作的時候,而bp針對棧段操作的資料。

 

3.3 變址定址

變址定址類似於基址定址,唯一不同之處在於這種定址使用的是變址暫存器(或稱索引暫存器)SI和DI。

例如:

mov [ds:si],dx
add ax,[es:di]
xor word[ds:si],0x8000

在以上指令中使用了變址暫存器si和di,因此可以認為以上指令是使用了變址定址方式。

 

同樣地,變址定址方式也允許帶一個偏移量,例如以下指令:

mov [ds:si+0x0100],al

對於變址定址,簡單一句話就是,只要指令中使用了變址暫存器SI或DI,就是使用了變址定址方式。