本文最初發表於2015-8-13,是由別的地方遷移過來的
匯編語言中的尋址方式十分重要,下面就是王爽老師總結出來的8086CPU尋址方式,不過,僅僅看這個表,是很難理解的。但是細細琢磨就可以看出一些規律。
1.關於圖中的注釋:
自定義符號:“()”表示取寄存器或內存單元中的值,idata表示常量。[BX]表示寄存器BX中的值是DS寄存器指向的段的偏移地址,DS是段寄存器。BP,SI,DI同理,不過(BX和BP)或(SI和DI)不能同時出現在一條語句中。在DEBUG程序下,可以直接[idata],但是在MASM下就必須用SREG:[idata](SREG是段寄存器)
基址就是基地址,相當於數軸原點O的比喻,變址相當於基地址的偏移地址,起到數軸中原點外一點的比喻,兩者都是段地址的偏移地址。
尋址就是尋找地址,CPU要讀取一個放在內存中的數據,首先要尋找它的地址,否則,找不到地址你就干不成事。這個通過地址總線尋找內存單元地址的過程就叫尋址。
(可以下載王爽的《匯編語言》來詳細地理解上述內容)
2.idata的位置
在常用格式舉例中可以發現,idata可以放在“[ ]”里面,也可以放在其外面,而寄存器bx,bp,si,di則不行,可以這樣記憶:idata因為其不是寄存器和內存空間,不受“[ ]”的管轄,因此可以自由穿梭在寄存器和內存空間之間。
3.寄存器相對尋址的理解
可以把寄存器看作一個數軸上的原點,idata就是那個數的絕對值,這樣理解就不會出錯了。如果你熟悉C語言,用數組,結構體就能更好地理解。
數組理解:把寄存器中的值看成是數組的首地址,idata就是元素的地址(一維數組),注意計算機中,地址的表示是從0開始,數制為16進制。人工讀內存時,若debug給出如下數據:0000:0200 00 01 02 03如果數據是字節形式存放的,就是四個數:0,1,2,3。如果是字形式存放就是兩個數(注意!!!):0100,0302。是倒過來的(高地址高字節低地址低字節)
結構體理解:寄存器是一個結構體變量,而idata就是一個成員。
4.基址變址尋址的理解
如上圖,也可以理解成一維數組,BX為數組首地址,SI為元素地址,表示的地址就是N+(SI ),也可以理解為二維數組,BX為行坐標,SI為列坐標。要注意的就是第一條提示的:基址不能同時出現,變址也如此。
5.相對基址變址尋址(難點)
這種定位方法很少用到,不過在復雜的程序中還是可以見到的。
這樣理解更簡單:
這種理解方法需要一定的C語言基礎,把BX看成一個結構體,idata為結構體中的一個數組的首地址,SI就是數組元素的地址。以前有學過C語言編程的人看一遍就可以輕松地理解這種方法。由於內存中的數據是一維線性排布的,引進二維數組的概念將使初學者很難理解二維數組在一維內存空間中的存放方式,也就更難理解尋址方式了。
利用二維數組來理解idata[BX][SI]:將idata作為一個二維數組的首地址,[BX]為行,[SI]為行中的列。這樣就確定了內存的地址了。
(二維數組A[x][y]的線性排布:A[0][0],A[0][1]…A[0][y-1],A[1][0]…A[1][y-1],A[2][0]…A[x-1][y-1])