尋址方式
所謂尋址方式就是表示指令中數據所在地址的方式。一共有七種尋址方案
立即數尋址
寄存器尋址
直接尋址
寄存器直接尋址
寄存器相對選址
基址變質尋址
相對基址變質尋址
在此之前,先介紹一個數據復制指令 MOV 指令, 格式是 MOV AX, BX 。 AX, BX是寄存器上一章介紹過的MOV就是指令。 指令的含義就是將BX的值復制給AX。C語言的表述就是AX=BX;
舉個例子 如果一開始 AX=5; BX=0;
MOV AX,BX 之后 AX = BX 都是0;
立即數尋址 / 寄存器尋址
MOV AX, 1 ; AX = 1
立即數尋址,我覺得稱不上尋址,因為他給出的不是地址,而就是實際的數字,上面的命令中 1 就是立即數,而AX就是寄存器尋址所以寄存器尋址就是直接使用寄存器,數據直接存入指定的寄存器
寄存器尋址可以使用的寄存器是AX(AL AH) BX(BL BH) CX(CL CH) DX(DL DH) SI DI SP BP等, 這些寄存器可以任意組合,舉例如下
MOV AX, BX ; AX = BX
MOV BX, AX ; BX =AX
MOV SI, DI ; SI = DI
MOV DI, SI ; DI = SI
這兩種尋址方式是不涉及內存的操作的,所以速度是最快的,所以為了性能考慮應該盡量多的使用這兩種尋址方式的操作。
注意: MOV 1, AX 是非法的,應為1就是常數,你不能給常數賦值
直接尋址
MOV AX, [1234H]
MOV AX, ES:[1234H]
直接尋址就是直接給出內存地址的尋址方式,格式是 段寄存器:[偏移地址] 偏移地址是立即數,用[]括起來。當然也可以直接省去前面的段寄存器寫作 [偏移地址],這樣匯編會自動選擇一個默認的段地址,一般來說是DS段寄存器。前面講過內存地址是 段地址X16+偏移地址,所以使用段寄存器:[偏移地址] 給出的地址就是 段寄存器的值X16 + 偏移地址,
舉例
MOV AX, DS:[1234H]
這句話的就是將DSx16+1234H處的數據復制給AX寄存器,假設DS=5000H 那么就是將內存51234處的數據復制給AX,具體是多少就要看當時內存中是什么數據了。
MOV AX, ES:[1234H]
就是顯示指定了使用的ES段寄存器,所以就是將ESx16+1234H處的數據復制給AX
注意 ":"前面只能跟着段寄存器 DS ES SS CS寄存器
這一條尋址方式其實是最基礎的尋址方式,接下來的其他幾種尋址方式都是只是[]中偏移地址的表示方式發生了一些變化而已。
寄存器直接尋址 / 基址尋址
MOV AX, [BX]
MOV AX,CS:[BX]
本質上和直接尋址是沒太大區別的,唯一的區別就是在直接尋之中[]中的數據是直接給出的,但是在寄存器間接尋址中這個數字是存儲在寄存器中而已。
這里有個限制就是[] 中能使用的寄存器只有 BX BP SI DI ,如果使用的是BX SI DI則默認的段寄存器是DS,如果是BP寄存器則默認使用SS寄存器。
當然如果特意指定寄存器那么就用指定的寄存器。
舉例 AX =1 BX = 1111H DS = 5000H
MOV AX, [BX] ; 等於MOV AX,DS:[1111H] 就是將51111H內存出的數據復制到AX中
寄存器相對尋址 / 相對基址尋址
MOV AX, [BX + 1111H]
在寄存器直接尋址的基礎上加上立即數,其他規則還是和寄存器直接尋址一樣的
舉例 AX =1 BX = 2222H DS=5000H
MOV AX, [BX + 1111H] ; 等於 MOV AX, DS:[2222H + 1111H] => MOV AX, DS:[3333H]
基址變址尋址
MOV AX,[BX+SI]
基址變址尋址就是用了兩個寄存器 {BX/BP}+{SI/DI}, 如果是出現BP寄存器則默認使用SS寄存器,否則默認使用DS寄存器.規則和寄存器間接尋址也是一樣的。
要注意的是這里分為兩組了寄存器 BX/BP 和SI/DI,一組中只能出現一個,即不能出現[ BX+BP ] 和 [SI+DI],從名字中就可以看出的 基址+變址,
BX 基地址寄存器
BP 基址指針寄存器(Base Point)
SI 源地址寄存器(Source Index)
DI 目的地址寄存器(Destination Index)
舉例 AX =1 BX=1111H SI=2222H DS= 5000H
MOV AX,[BX+SI]; 等於 MOV AX, DS:[BX+SI] => MOV AX, DS:[1111H+2222H] => MOV AX, DS:[3333H]
相對基址變址尋址
MOV AX,[BX+SI+4444H]
可以看出就是在基址變址尋址的基礎上加上了立即數其他規則不變
舉例 AX =1 BX=1111H SI=2222H DS= 5000H
MOV AX,[BX+SI+4444H]; 等於 MOV AX, DS:[BX+SI+4444H] => MOV AX, DS:[1111H+2222H+4444H] => MOV AX, DS:[7777H]
總結:
在我看來其實就三種尋址方式
1. 立即數尋址 MOV AX, 1 直接給出數據
2. 寄存器尋址 MOV AX, BX 地址是寄存器
3. 內存尋址 MOV AX, 段寄存器 : [地址]
地址使用 [] 括起來,[] 中的結果就是數據在內存中的偏移地址,[] 可以使用兩組寄存器 (BX/BP 和 SI/DI) 和 立即數的任意組合,同組寄存器不能同時出現,段寄存器如果不指定則如果出現了BP寄存器就默認使用SS段寄存器否則默認使用DS寄存器
寄存器間接尋址 = [ 只用一個寄存器]
寄存器相對選址 = [用一個寄存器+立即數]
基址變質尋址 = [用兩個寄存器]
相對基址變質尋址 = [用兩個寄存器+立即數]
寫個公式就是
[地址] = [ {BX | BP | 空} + {SI | DI | 空} + {立即數 | 空} ] = [ 基址 + 變址 + 相對(包含其他寄存器)/ 直接(不包含其他寄存器) ]
BX | BP = 基址
SI | DI = 變址
立即數 = 相對(包含其他寄存器)/ 直接(不包含其他寄存器)
這里面是 全用、任選其一、任選其二,名字就根據選用情況來搭配
比如
[基址(BX|BP)+立即數] = 相對基址尋址
[基址(BX|BP)+變址] = 基址變址尋址
[基址(BX|BP)+變址+立即數] = 相對基址變址尋址
其實這些尋址方式在使用匯編寫代碼的時候都是有對應的使用場景的,這個在以后會介紹的。