尋址
匯編語言中,操作碼用助記符表示,操作數則由尋址方式體現。8086處理器只有輸入輸出指令與外設交換數據,除外設數據外的數據尋址方式有3類:
用常量表達的具體數值(立即數尋址)
用寄存器名表示的其中內容(寄存器尋址)
用存儲器地址代表保存的數據(存儲器尋址)
立即數尋址
立即數尋址(或立即尋址)中,指令需要的操作數緊跟在操作碼之后作為指令機器代碼的一部分,並隨着處理器的取指操作從主存進入指令寄存器。
這種操作數用常量形式直接表達,從指令代碼中立即得到,被稱為立即數(Immediate)。
立即數尋址方式只用於指令的源操作數,在傳送指令中常用來給寄存器和存儲單元賦值。

簡而言之,立即數尋址就是 操作碼 + 立即數,其中立即數是常量形式的,可以直觀的看到。
例如,將數據0102H傳送到AX寄存器的指令,可以書寫為:
mov ax, 0102h ; 指令代碼:B8 02 01
8086處理器規定數據高字節存放於存儲器高地址單元、數據低字節存放於低地址單元,如圖右所示。
寄存器尋址
寄存器尋址方式的操作數存放在處理器的寄存器中。通常直接使用寄存器名表示它所保存的數據,即寄存器操作數。
絕大多數指令采用通用寄存器尋址(8086處理器是16位的AX、BX、CX、DX、SI、DI、BP和SP,以及8位
的AL、AH、BL、BH、CL、CH、DL和DH),部分指令支持專用寄存器,例如段寄存器、標志寄存器等。
寄存器尋址方式簡單快捷,是最常使用的尋址方式。

凡是只使用寄存器名(無其他符號,例如中括號、變量名等)的操作數都為寄存器尋址。
mov al,ah
注意:MOV指令不允許把8位寄存器的數據傳送到16位寄存器中。下面演示錯誤的用法:
mov di,dh ;di是16位的,dh是8位的,所以出錯。
存儲器尋址
如何尋址主存中存儲的操作數就稱為存儲器尋址方式,也稱為主存尋址方式。編程時,存儲器地址使用包含段選擇器和偏移地址的邏輯地址。
這里復習一下邏輯地址、偏移地址和物理地址之間的關系:
段基地址左移4位(十六進制一位) + 偏移地址 = 20位物理地址
邏輯地址是應用程序所看到的地址,段基地址和偏移地址共同組成邏輯地址,可以通過尋址獲取物理地址。
段寄存器的默認和超越
段寄存器(段選擇器)有默認的使用規則。尋址存儲器操作數時,段寄存器不用顯式說明,即數據就在默認的段中,一般是DS段寄存器指向的數據段;如果采用BP或SP作為基地址指針,則默認使用SS段寄存器指向堆棧段。

如果不使用默認的段選擇器,需要書寫段超越指令前綴顯式說明。段超越指令前綴,是一種只能跟隨具有存儲器操作數的指令之前的指令,其助記符是段寄存器名后跟英文冒號,即CS:、SS:、DS:或ES:。
偏移地址的組成
存儲器操作數尋址使用的偏移地址常被稱為有效地址EA(Effective Address)。
為了方便各種數據結構的存取,8086處理器設計了多種主存尋址方式,但可以統一表達如下:

其中基址寄存器是BX或BP,變址寄存器是SI或DI,位移量是8或16位有符號值。
直接尋址
存儲器的直接尋址方式的有效地址只有位移量部分,直接包含在指令代碼中,直接尋址常用於存取變量。

例如,將變量COUNT內容傳送給AX的指令:
mov ax,count ;也可以表達為mov ax,[count]
匯編語言的指令代碼中直接書寫變量名就是在其偏移地址(有效地址)的存儲單元讀寫操作數。
假設操作系統為變量COUNT分配的有效地址是2000H,則該指令的機器代碼是:A1 00 20,反匯編的指令形
式為:MOV AX, DS:[2000H],其源操作數采用直接尋址。
MASM 匯編程序使用中括號表示偏移地址,變量 COUNT 也可以采用加有中括號[COUNT]的形式,體現其訪問存儲單元的特性。
寄存器間接尋址
有效地址存放在寄存器中,就是采用寄存器間接尋址存儲器操作數。
MASM匯編程序使用英文中括號括起寄存器表示寄存器間接尋址。8086 處理器只有基址寄存器BX和兩個變址寄存器SI、DI可以作為寄存器間接尋址的寄存器。
下面的前兩條指令的源操作數、后兩條指令的目的操作數都是寄存器間接尋址方式:
mov al,[bx] ;字節量傳送,BX間接尋址
mov cx,[si] ;字量傳送,SI間接尋址
mov [di],dl ;字節量傳送,DI間接尋址
mov word ptr[di],1394h ;字量傳送,DI間接尋址
寄存器間接尋址中寄存器的內容是偏移地址,相當於一個地址指針。
指令“MOV AL, [BX]”執行時,如果BX=2000H,則該指令功能等同於“MOV AL, DS:[2000H]”:

設計寄存器間接尋址的主要目的是只要將數組或字符串首地址(或末地址)賦值給通用寄存器,利用寄存器間接尋址就可以訪問到數組或字符串頭一個(或最后一個)元素或字符。
寄存器相對尋址
寄存器相對尋址的有效地址是寄存器內容與位移量之和。(常用於訪問數組和結構)
8086只有BX和BP、SI和DI可作為寄存器相對尋址的寄存器。

mov si, [bx+4] ;源操作數采用寄存器相對尋址還可表達為:[4][bx]或4[bx]
這條指令中,源操作數的有效地址由BX寄存器內容加位移量4獲得,默認與BX寄存器配合的是DS指向的數據段
基址變址尋址
使用基址寄存器內容加上變址寄存器內容形成有效地址尋址存儲器操作數被稱為基址變址尋址。
8086的基址寄存器是BX和BP,變址寄存器是SI和DI,使用BP默認訪問堆棧段,其他默認訪問數據段,可以使用段超越。
mov al,[bx+si] ;源操作數在數據段,也可以表達為:[bx][si]
mov ax,[bp+di] ;源操作數在堆棧段,也可以表達為:[bp][di]
mov ax,ds:[bp+si] ;源操作數在數據段,也可以表達為:ds:[bp][si]
相對基址變址尋址
采用相對基址變址尋址,存儲器操作數的有效地址由基址寄存器內容、變址寄存器內容及位移量相加獲得。同樣,8086的基址寄存器是BX和BP,變址寄存器是SI和DI,使用BP默認訪問堆棧段,其他默認訪問數據段,可以使用段超越。
mov cx,[bx+si+4] ;源操作數也可以表達為:4[bx+si]
mov ax,80h[bx+di] ;源操作數也可以表達為:80h[bx][di]
mov dx,count[bp][di] ;源操作數也可以表達為:[bp+di+count]
