8086CPU中的尋址方式一


尋址方式

定義

尋址方式:求操作數所在地或者所在存儲器地址單元的方式。

指令中的操作數,大多數都在存儲器單元當中,也可以在寄存器里面,也可以是在指令中立即給出的常數。我們都把求得她們的方式歸屬於尋址方式。


類型

尋址方式按求得的操作數的目的不同,可以分為兩類:

  1. 數據用

  2. 程序要實現轉移的地址用

如果要實現段內轉移,就需要求得段內偏移地址給IP用,如果要實現段間轉移,除了偏移地址外,還需要求得目的地的段地址給CS用。

要計算的數據的所在存儲地址怎么得到,或者轉移的地址內容的所在存儲地址怎么得到,就需要用以一種尋址方式去求得。


關於數據的尋址方式

1.立即數尋址

要尋找的操作數在指令中立即給出,直接以常數給出。

mov AX,1234H

AX是目的操作數,1234H是源操作數,對於源操作數而言,采用的就是立即數尋址。指令中要傳送給AX的數據在哪里呢?指令中立即給出了。這就叫立即數尋址。

要搞清楚8086立即尋址,就需要了解誰和誰之間可以傳送

從圖中可知,在8086當中,立即數只能作為源操作數。

立即數傳送數據時要類型明確

mov [0002H],15H

中括號里面表示的是地址,這條語句是把立即數15H送到地址為0002H的存儲器單元中。

但是我們只知道地址是多少,不知道存儲器單元的存儲類型是什么?語法錯誤。類型不明確。這中問題只要源操作數和目標操作數有一方明確,雙方均能明確(不一致另說)。雙方不明確,類型不明確。

mov WORD PTR [0002H],15H

如果要傳送數據給段寄存器,不能直接立即數傳送,要按箭頭走。

從圖中也可以看出,段寄存器CS單獨划分出來,因為用戶無法改變CS的內容,和IP寄存器一樣,開機的內容由操作系統完成。執行期間是由CPU完成轉移指令改變。CS和IP不能做目標操作數,但是可以做源操作數。


2.寄存器尋址

指要尋找的操作數在某寄存器當中

mov AX,BX

對於源操作數而言,要操作的數據在BX寄存器中,這就是寄存器尋址。同樣的,目的操作數而言,也是寄存器尋址。

當源和目標是寄存器尋址時,一定要注意類型要一致

mov AX,CL

AX是16位的,而CL是8位的,語法錯誤。


3.存儲器尋址

指要尋找的操作數在存儲器某單元中,存放操作數的單元的EA段內偏移地址,可以由以下5種尋址方式求得:

1.直接尋址

直接尋址就是在指令中直接寫出存儲單元的有效地址

mov AL,[2000H]

將存儲器單元地址為2000H的字節內容送給AL(實際上決定是字節內容的是AL的類型)

但這種方法不常用,一般都將地址符號化——變量名。

在DS段有下列變量定義:

dat1 DB 12H
dat2 DB 34H
...

實際中數據段定義的變量很多。

在CS段執行程序

mov AL dat1

dat1代表的就是一個地址,所以源操作數的尋址方式是直接尋址。在dat1里面的內容送給AL。執行完(AL)=12H。

mov dat2 dat1

源和目標操作數都采用直接尋址,想把dat1里內容直接送給dat2單元里面。但是語法錯誤。如上圖3.3,寄存器之間可以互傳數據,但是存儲器單元之間不可以直接操作(任何操作)。不能直接傳送數據,也不能直接運算。

只能通過寄存器做中轉,讀出來后,再將寄存器里面的值送給存儲器。

當然也要遵循前后類型一致。如

mov WORD PTR dat1,AX

而不能直接進行數據傳送,因為dat1是字節變量8位,AX是16位。

mov dat1,AX

2.寄存器間接尋址

指操作數在存儲器中,段內偏移地址由寄存器間接給出。能做寄存器間接尋址的寄存器只有3個——BX,SI,DI。

這三個寄存器默認的段地址默認在DS數據段

dat1 DB 12H
dat2 DB 34H

把dat1內容送給AL,寄存器間接尋址方式為:

mov BX, OFFSET dat1
mov AL,[BX]

OFFSET dat1把dat1的偏移地址屬性拿出來了,所以對於源操作數而言屬於立即數尋址。

[BX]中括號里面是把BX的內容作為DS段的段內有效地址,屬於寄存器間接尋址。


3.寄存器相對尋址

指的是操作數在存儲器某個單元當中,有效地址由兩部分組成:

第一部分在一個基址寄存器當中——BX,BP,SI,DI 四者之一。第二部分是一個8位或16位的DISP相對位移量。兩部分之和就是操作數所在存儲單元的地址。

如果相對位移量是一個常數,那么對應的邏輯段的段地址由寄存器部分默認決定給出。BX\SI\DI默認在DS段,BP默認在堆棧段SS。

如果相對位移量是一個變量,會自動取變量的段內偏移地址作為位移量,此時邏輯段的段地址由變量所在的段決定。

當然我們可以添加段超越前綴,改變寄存器指向的段地址。

這個方式容易和寄存器間接尋址混淆,但我覺得其實就是間接尋址基礎上加上個位移量,但是又加上了一些規則。

mov [BP],AL

注意,[BP]是寄存器相對尋址,因為BP不能用作間接尋址。所以這條指令,是把AL的內容送給某個存儲器單元,這個單元的地址一部分是BP內容,一部分為相對位移量,這里為0,即SS:(BP)+0。

ALmov [BX]+3,AL

目標操作數是寄存器相對尋址,存儲器單元地址為BP內容+3.

這種方式也可以寫成

mov [BX+3],AL

結果相同,匯編后代碼相同,只是書寫格式不同。

也可以寫成

mov 3+[BX],AL

當位移量在左邊時,加號可以省略,即

mov 3[BX],A

當位移量是一個變量時

dat1 DB 12H
mov dat1[BX],AL

dat1定義在DS段,則dat1[BX]代表的存儲器地址為 DS:OFFSET dat1+(BX)

BP相對尋址的目的

添加BP進行相對尋址的目的,是為了在不破壞堆棧指針SP的情況下,將堆棧里面的值讀取出來

PUSH AX
PUSH BX
PUSH CX

現在將AX內容送給DX,但不能破壞SP內容,怎么做·?

mov BP,SP
mov DX,[BP]+4

4.基址、變址尋址

指的是操作數在存儲器某個單元當中,有效地址由兩部分組成:第一部分在一個基址寄存器當中——BX,BP兩者之一;第二部分在一個變址寄存器中——SI、DI兩者之一。兩部分之和就是操作數所在存儲單元的段內地址。段地址由基址寄存器默認決定。這種尋址方式叫做基址、變址尋址。

如,用基址、變址尋址方式,將dat1內容送給AL

dat1 DB 12H
dat2 DB 34H
...
mov BX,OFFSET dat1
mov SI,0
mov AL,[BX][SI]

5.基址、變址相對尋址

由第三種和第四種結合而來。

指的是操作數在存儲器某個單元當中,有效地址由三部分組成:第一部分在一個基址寄存器當中——BX,BP兩者之一;第二部分在一個變址寄存器中——SI、DI兩者之一;第三部分是一個8位或16位的DISP相對位移量。三部分之和就是操作數所在存儲單元的地址。這種尋址方式叫做基址、變址相對尋址。

同樣的,和第三種一樣,如果相對位移量是一個常數,那么對應的邏輯段的段地址由寄存器部分默認決定給出。BX默認在DS段,BP默認在堆棧段SS。

如果相對位移量是一個變量,會自動取變量的段內偏移地址作為位移量,此時邏輯段的段地址由變量所在的段決定。

如,用基址、變址相對尋址方式,將dat1內容送給AL

dat1 DB 12H
dat2 DB 34H
...
mov BX,0
mov SI,0
mov AL,dat1[BX][SI]

4.隱含尋址

隱含尋址的含義是,指令中並沒有寫明操作數,但是CPU知道操作數在哪個地方。

PUSH AL

指令只有單操作數,且是源操作數,沒有指明目標操作數在哪里,但是CPU知道怎么做:

  1. SP=(SP)-2

  2. (SS:(SP))=AL

在8086中,字符串的指令,對於源和目標操作數都是隱含尋址。


實際當中,我們只需要選擇其中之一作為尋址方式即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM