0 前言
眾所周知,對于8086匯編語言,有幾大尋址方式,不過我覺得這個好墨跡,會用就可以了,為什么命名這么多,這次只說本質,不說命名,至于命名,還是得知道,畢竟是大部分人公認的,不能反抗這點哦,但是你知道,不代表你真的要這么去想。
1 何為尋址?何為尋址方式?
看了很多資料,讓人眼花繚亂,各種專業詞匯讓人眼花繚亂,撲朔迷離,我直接用最簡練的語言說明。
- 尋址,就是找數據
- 尋址方式,就是找數據的方法
接下來,根據數據的位置,我再細說一下各種尋址方式。
2 立即數尋址
一句話,在指令中找數據。
訪問方式: 找指令的時候,順便將數據帶過來了,怎么找指令就怎么找它。
舉例:
mov ax,1000h
1000h
就是立即數,也就用到了立即數尋址。
3 寄存器尋址
一句話,在寄存器中找數據。
訪問方式: 直接寫上寄存器的名字,就能訪問了。
舉例:
mov ax,1000h
ax
就是寄存器的名稱,也就用到了寄存器尋址。
4 存儲器尋址
一句話,在存儲器中找數據。(這里的存儲器,通常情況下指的是主內存)
訪問方式: 表示出存儲單元的地址,就能訪問了。
唯獨存儲器尋址比較麻煩,因為它表示地址的方式有很多種。
但是在我這里,也就一句話,地址的形成方式是:BX,BP,SI,DI和立即數
的各種組合。
其實也就這些而已,只不過還有一些其他的規則限定,我也來細說一下(順便說一句,這些東西,先看懂理解,然后自己動手試一下,多試試就學會了,不要背)。
BX —— based register——基地址寄存器
BP —— base point——基礎指針
SI —— source index——源變址寄存器
DI —— destination index——目的變址寄存器
先給出你英文全稱,你就很快能夠知道,為什么是這幾個寄存器了。
4.1 語法格式
mov ax,dataSegmentName
mov ds,ax
mov 目標,[address]
使用存儲器尋址的時候,需要
- 設置好DS的值
- 再設置
[address]
的值,address的內容,就是上面說的
4.2 各種存儲單元地址的生成方式
這里,我結合大家公認的命名,以及我自己的觀點,闡述這些內容。
不管是什么尋址方式,本質就是為了生成address的值,生成數值的本質,就是我說的5個東西(bx,bp,si,di,立即數
)進行基本的數學運算。
- 寄存器直接尋址
由立即數提供偏移地址。
mov ax,ds:[1000h]
在匯編語言中,立即數作為偏移地址,前面需要顯式地加上提供段地址的寄存器,另外,這種顯式的方式,一樣可以應用于后面的方式,但是不是強制的。
- 寄存器間接尋址
由bx,si,di
提供偏移地址,注意沒有BP,至于原因,與硬件設計和語法設定有關,不必追究。
mov ax,[bx] ; 也可以寫上 mov ax,ds:[bx]
mov ax,[si]
mov ax,[di]
另外,也可以使用其他段寄存器(ss,cs,es)提供段地址,顯示加上就可以,mov ax,ss:[bx]
,這樣就由ss提供段地址,bx提供偏移地址。
- 基址尋址
由bx + 位移量
或bp + 位移量
提供偏移地址。
特殊:只有bp提供偏移地址的時候,默認ss寄存器提供段地址,其他的默認ds。
mov ax,[bx + 10H] ; 本質 mov ax,ds:[bx + 10H]
mov ax,[bp + 10H ]; 本質 mov ax,ss:[bp + 10H]
另外,在尋址范圍之內,位移量可正可負可為0,下面的4,5也是這樣。
- 變址尋址
由si + 位移量
或di + 位移量
提供偏移地址。
mov ax,[si - 10h]
mov ax,[di - 10h]
- 基址變址尋址
由1個基址寄存器 + 1個變址寄存器 + 位移量
提供偏移地址,只有含有BP,就是SS提供段地址。
mov ax,[bx + si + 10h]
4.3 位移量為什么還可以是負數?
首先,你需要了解的是,這里的負數是十進制的負數,編碼方式是二進制補碼。
位移量是正數,就代表在基礎之上,加了東西
位移量是負數,就代表在基礎之上,減了東西
說白了就是,可加可減,反正都是找數據,怎么找都可以,畫個圖你就明白了。
你可能問,如果是bx - 11h
,但是bx < 11h
,不是成了負數?注意,在二進制世界,減過頭了,叫溢出,是正溢出,溢出的結果,就是循環回去。 我再畫個圖:
對于有符號數
正溢出:兩數運算,大于最大的正數,進入負數區域
負溢出:兩數運算,小于最小的負數,進入正數區域
4.4 小結
注意,位移量其實就是個常數,也可以說成立即數,大多數情況不用區分。
1個:[常數]
,[bx]
,[si]
,[di]
2個:[bx + 位移量]
,[bp + 位移量]
,[si + 位移量]
,[di + 位移量]
3個:[(bx或bp)+ (si或di)+ 位移量]
,注意,不可以是[bx + bp + 位移量]
或[si + di + 位移量]
。
4.5 思想方法
需要注意的是,以上是數學運算,都是加減法,但是這只是在8086中,未來,還會有乘法的出現,但是依然沒有脫離本質,address = { {BX,BP,SI,DI和立即數} 的基本數學混合運算}。
希望你明白,之所以不要你去專注于各種被限定的尋址方式,是因為那些不是本質,掌握本質,把握知識源頭,才能夠更好地應對未來。
在x86-32匯編語言中,地址的生成方式,又有所改變。
例如:mov dword ptr [ebp+eax*4-6Ch],edx
,如果你記憶的是8086匯編于尋址方式,那么這個新的方式,你依然要去記憶,但是如果你掌握的是本質,你就知道,這不過是在生成地址的過程中,增加了一個乘號而已,之后你再去探索一下,為什么增加這個乘號,你就可以快速透徹理解和掌握它了。
5 注意事項
需要注意的是,這些理解,是為了讓你抓住本質,但是并不代表,你只知道這些就可以了,內些雜亂的命名,依然有存在的價值,你同樣需要掌握。
最后,還有一個重要的感悟,那就是任何操作數,都需要應用到這些尋址方式,因為計算機的本質就是處理數據,數據又需要通過尋址來找到。
推薦閱讀:計算機處理信息的本質,是二進制數的運算(本文第2節)