8086匯編語言初學者教程(第二部分)
尋址方式
我們可以通過下面的四個寄存器來尋址 BX, SI, DI, BP.
通過計算[]符號中的值,我們可以訪問到不同內存單元的值。具體組合
請看下表:
[BX + SI] [BX + DI] [BP + SI] [BP + DI] |
[SI] [DI] d16 (variable offset only) [BX] |
[BX + SI] + d8 [BX + DI] + d8 [BP + SI] + d8 [BP + DI] + d8 |
[SI] + d8 [DI] + d8 [BP] + d8 [BX] + d8 |
[BX + SI] + d16 [BX + DI] + d16 [BP + SI] + d16 [BP + DI] + d16 |
[SI] + d16 [DI] + d16 [BP] + d16 [BX] + d16 |
d8 - 表示8位偏移量
d16 - 表示16位偏移量
偏移量可以是一個立即數或者是一個變量的偏移,或者二者兼備。
這取決於編譯器如何計算單獨的立即數。
偏移量可以在[]符號里面或者外面,這不影響編譯器生成相同的
機器碼。
偏移量是一個有符號數,可以是正數或者負數。
一般說來,8位或者16位,對於編譯后的結果是有影響的。
例如,假定 DS = 100, BX = 30, SI = 70。
如下尋址方式 [BX + SI] + 25 計算物理地址為
100 * 16 + 30 + 70 + 25 = 1725
默認下,DS 寄存器應用在除了BP寄存器之外的所有物理
地址計算中,寄存器是和SS寄存器一起工作的。
用過下面的表,你可以和輕松記住誰和誰是關聯在一起使用的。
上表中,你可以從每一列中選擇一個或者忽略任意一個列。比如,
可以看到,BX 和 BP始終不會選到一起。SI 和 DI不會選到一起。
這是一個計算地址模式[BX+5]
段寄存器(CS, DS, SS, ES) 中數值被稱作 "段偏移" 。
目的寄存器(BX, SI, DI, BP) 中數值被稱作"偏移量"
比如,ds中數值為1234h,si中數值為7890h,可以記作
1234:7890 物理地址為 1234h * 10h + 7890h = 19BD0h
在編譯過程中使用如下聲明數據類型
BYTE PTR - 表示字節
WORD PTR - 表示字(2個字節)
例如:
BYTE PTR [BX] ;按字節訪問
or
WORD PTR [BX] ;按字訪問
Emu8086 容許使用如下更簡潔的前綴
b. - 等價於上面的 BYTE PTR
w. - 等價於上面的 WORD PTR
有時,編譯器可以自動計算出數據類型,但是如果一個參與運算
的數是立即數,這種方法就不可靠了。
MOV 指令
- 將第二個操作數(源)拷貝到第一個操作數(目的)指定位值
- 源操作數可以是立即數,通用寄存器或者內存單元
- 目的寄存器可以是通用寄存器或者內存單元
- 源和目的必須是同樣大小,要么都是字節要么都是字
操作類型如下:MOV REG, memoryREG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP. memory: [BX], [BX+SI+7],變量, 等等 immediate: 5, -24, 3Fh, 10001101b, 等等. |
mov 指令只支持如下段寄存器:MOV SREG, memorySREG: DS, ES, SS, 注意 CS 只能作操作源 REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP. memory: [BX], [BX+SI+7], variable, 等等 |
MOV指令不能用來設置CS和IP寄存器的值。
下面是一個使用 MOV 指令的例子: #MAKE_COM# ; 表示,這個是一個com程序 ORG 100h ;COM 程序必須的 MOV AX, 0B800h ; 將ax設置為 B800h. MOV DS, AX ; 將 AX 值拷貝到 DS. MOV CL, 'A' ; 將ASCII 碼 'A'的值傳送到cl,這個值是 41h. MOV CH, 01011111b ; 將ch設置為二進制的01011111b MOV BX, 15Eh ; 將 BX 設置成 15Eh. MOV [BX], CX ; 將 CX 放到 bx 指出的內存單元 B800:015E RET ; 返回操作系統 |
你可以將上面的程序貼入Emu8086代碼編輯器,接下來按下
[complie and emulate] (或者按F5)
模擬窗口將顯示這個程序已經調入,點擊[single step]觀察
寄存器數值變化。
你可以猜到 ";" 表示注釋,編譯器忽略在";"后面的一切
程序結束后,你可以看到如下窗口
事實上,上面程序是將字符直接寫入顯示內存。
通過上面的例子,你可以發現 MOV 指令是非常有用的。