1. 程式人生 > >彙編的8種定址方式,以及2個預設段暫存器

彙編的8種定址方式,以及2個預設段暫存器

16位CPU所含有的暫存器有(見圖2.1中16位暫存器部分):
4個數據暫存器(AX、BX、CX和DX)
2個變址和指標暫存器(SI和DI) 2個指標暫存器(SP和BP) ,32位CPU增加2個16位的段暫存器:FS和GS。
4個段暫存器(ES、CS、SS和DS)
1個指令指標暫存器(IP) 1個標誌暫存器(Flags)
一共14個暫存器,或者16個

16位CPU內部有20根地址線,其編碼區間為:0000H~FFFFFH,所以,它可直接訪問的物理空間為1M(220)位元組。
如果用16位暫存器來訪問記憶體的話,則只能訪問記憶體的最低端的64K,其它的記憶體將無法訪問。為了能用16位暫存器來有效地訪問1M的儲存空間,16位CPU採用了記憶體分段的管理模式,並引用段暫存器的概念。


個人猜測:堆疊有1M的限制,是不是因為這個歷史原因?

實體地址PA=段地址×16 + 偏移量(Offset)
有效地址EA=Effective Address(段內偏移)

CS:IP 段暫存器CS指向存放程式的記憶體段,IP是用來存放下條待執行的指令在該段的偏移量,把它們合在一起可在該記憶體段內取到下次要執行的指令。
SS:SP 段暫存器SS指向用於堆疊的記憶體段,SP是用來指向該堆疊的棧頂,把它們合在一起可訪問棧頂單元。另外,當偏移量用到了指標暫存器BP,則其預設的段暫存器也是SS,並且用BP可訪問整個堆疊,不僅僅是隻訪問棧頂。
DS:ALL 段暫存器DS指向資料段,ES指向附加段,在存取運算元時,二者之一和一個偏移量合併就可得到儲存單元的實體地址。該偏移量可以是具體數值、符號地址和指標暫存器的值等之一,具體情況將由指令的定址方式來決定。
ES:DI

在進行串操作時,其目的地址的段暫存器規定為ES
總結:程式頻繁訪問的資料段用DS來指向,不太經常訪問的資料段可用ES、FS和GS等來指向。

1.立即定址方式 MOV AH, 80H(直接給暫存器賦值)
2. 暫存器定址方式(源或者目的有一個是暫存器)
2.1) 源運算元是暫存器定址方式
如:ADD VARD, EAX  ADD VARW, AX   MOV VARB, BH等。
其中:VARD、VARW和VARB是雙字,字和位元組型別的記憶體變數。
2.2) 目的運算元是暫存器定址方式
如:ADD BH, 78h    ADD AX, 1234h   MOV EBX, 12345678H等。
2.3) 源和目的運算元都是暫存器定址方式
如:MOV EAX, EBX   MOV AX, BX     MOV DH, BL等。
3. 直接定址方式

(地址值在括號裡)
MOV BX, [1234H] (預設使用DS)
MOV ES:[1000H], AX
4. 暫存器間接定址方式(暫存器在括號裡)
MOV BX,[DI]
運算元的有效地址用SI、DI、BX和BP等四個暫存器之一來指定,稱這種定址方式為暫存器間接定址方式。
若有效地址用SI、DI和BX來指定,則其預設的段暫存器為DS;
若有效地址用BP來指定,則其預設的段暫存器為SS(即:堆疊段)。
5. 暫存器相對定址方式(一個暫存器和一個立即數在括號裡,並且還要計算)
MOV BX, [SI+100H]
6. 基址加變址定址方式(兩個暫存器在括號裡,並且還要計算)
MOV BX, [BX+SI]
7. 相對基址加變址定址方式(兩個暫存器在括號裡和一個立即數在括號裡,並且還要計算)
MOV AX, [BX+SI+200H]

幾個例子:
例子1. MOV BX, [SI+100H]
定址路線為:
PA=(DS)*16+(SI)+100H

例子2. MOV BX, [BX+SI]
定址路線為:
PA=(DS)*16+=(BX)+(SI)

例子3. MOV AX, [BX+SI+200H]
定址路線為:
PA=(DS)*16+(BX)+(SI)+200H

取資料的規則:高高低低
比如記憶體單元12445H的Byte值為15H,12446的Byte內容為27H,那麼12445的Word值為2715H,而BX的值也是2715.
注:為了簡化理解,低地址在上面,高地址在下面(所謂向下生長)。與堆疊模型一致,參考:
http://www.cnblogs.com/findumars/archive/2012/10/28/2743121.html

8. 32位地址的定址方式
在用16位暫存器來訪問儲存單元時,只能使用基地址暫存器(BX和BP)和變址暫存器(SI和DI)來作為地址偏移量的一部分。
但在用32位暫存器定址時,不存在上述限制:
32位基址暫存器是:EAX、EBX、ECX、EDX、ESI、EDI、EBP和ESP;
32位變址暫存器是:EAX、EBX、ECX、EDX、ESI、EDI和EBP(除ESP之外)。
計算公式:基址暫存器+變址暫存器+比例因子+偏移常量。
段暫存器的判斷與使用:
1)地址中暫存器的書寫順序決定該暫存器是基址暫存器,還是變址暫存器,例如:
[EBX+EBP]中的EBX是基址暫存器,EBP是變址暫存器。
[EBP+EBX]中的EBP是基址暫存器,EBX是變址暫存器。
2)基址暫存器是EBP或ESP時,預設的段暫存器是SS,否則,預設的段暫存器是DS,例如:
MOV AX, [123456H] ;預設段暫存器DS
MOV EAX, [EBX+EBP] ;預設段暫存器DS
MOV EBX, [EAX+100H] ;預設段暫存器DS
MOV EBX, [EBP+EBX] ;預設段暫存器SS
MOV [ESP+EDX*2], AX ;預設段暫存器SS
MOV AX, [ESP] ;預設段暫存器SS
3)在指令中,如果使用段字首的方式,那麼,顯式段暫存器優先。
MOV EDX, ES:[EAX*4+200H] ;顯式段暫存器ES
MOV EBX, GS:[EAX+EDX*2+300H] ;顯式段暫存器GS

為了明確指令中儲存單元的屬性,可把指令“MOV [BX], 1H”可改寫成:
MOV byte ptr [BX], 1H   或  MOV word ptr [BX], 1H

一個位元組的內容是該位元組單元記憶體放的二進位制資訊;
一個字的內容是該字地址所指向的單元及其後繼一個單元的內容拼接而成;
一個雙字的內容是該字地址所指向的單元及其後繼三個單元的內容拼接而成。