第八章
定義描述性符號reg表示一個寄存器,sreg描述一個段寄存器
reg:ax、bx、cx、dx、ah、al、bh、bl、ch、cl、dh、dl、sp、bp、si、di
sreg:ds、ss、cs、es
8.1 bx、si、di和bp
在8086CPU中,只有這4個寄存器可以用在[……]中來進行內存單元的尋址
下面指令是錯誤的
mov ax,[cx]
mov ax,[ax]
mov ax,[dx]
mov ax,[ds]
在[……]中,這4個寄存器可以單個出現,或只能以4種組合出現:bxhesi、bx和di、bp和si、bp和di
如下指令也是正確的
mov ax,[bx+si+idata]
mov ax,[bp+si+idata]
如下指令是錯誤的
mov ax,[bx+bp]
mov ax,[si+di]
只要在[……]中使用寄存器bp,而指令中沒有顯性地給出段地址,段地址就默認在ss中
mov ax,[bp] ;等價於mov ax,ss:[bp]
mov ax,[bp+si] ;等價於mov ax,ss:[bp+si]
8.2 機器指令處理的數據在什麼地方
指令在執行前,所要處理的數據可以在3個地方:CPU內部、內存、端口
8.3 彙編語言中數據位置的表達
1、立即數(idata)
對於直接包含在機器指令中的數據(執行前在CPU的指令緩衝區中),在彙編指令中直接給出
mov ax,1
add bx,2000h
mov al,'a'
2、寄存器
指令要處理的數據在寄存器中,在彙編指令中給出相應的寄存器名
3、段地址(SA)和偏移地址(EA)
指令要處理的數據在內存中
8.4 尋址方式
[bx+idata] [bx].idata idata[bx] [bx][idata]
[bx+si+idata] [bx].idata[si] idata[bx][si]
8.5 指令要處理的數據有多長
8086CPU的指令,可以處理兩種尺寸的數據,byte和word,所以在機器指令中要指明,指令進行的是字操作還是字節操作
1、通過寄存器名指明
2、在沒有寄存器名存在的情況下,用操作符X ptr指明內存單元的長度。X在彙編指令中可以爲word或byte
mov word ptr ds:[0],1
inc word ptr [bx]
inc byte ptr ds:[0]
add byte ptr [bx],2
在沒有寄存器參與的內存單元訪問指令中,用X ptr是很必要的,否則CPU無法得知所要訪問的單元是字單元還是字節單元
有些命令是默認長度的,如push
8.6 尋址方式的綜合應用
關於DEC公司的一條記錄(1982年)如下
公司名稱:DEC
總裁姓名:Ken Olsen
排名:137
收入:40
著名產品:PDP
這些數據在內存中的存儲如圖
到了1988年DEC公司的信息有了如下變化
1、Ken Olsen在富豪榜上的排名已升至38位
2、DEC的收入增加了70億美元
3、該公司的著名產品已變成VAX系列
mov ax,seg
mov ds,ax
mov bx,60h
mov word ptr [bx+0ch],38
add word ptr [bx+0eh],70
mov si,0
mov byte ptr [bx+10h+si],'V'
inc si
mov byte ptr [bx+10h+si],'A'
inc si
mov byte ptr [bx+10h+si],'X'
c語言中有結構體,可以按照c語言的風格寫一下這個程序
mov ax,seg
mov ds,ax
mov bx,60h
mov word ptr [bx].0ch,38
add word ptr [bx].0eh,70
mov si,0
mov byte ptr [bx].10h[si],'V'
inc si
mov byte ptr [bx].10h[si],'A'
inc si
mov byte ptr [bx].10h[si].'X'
在編程時,以結構化的角度看待所要處理的數據,bx定位整個結構體(公司)。idata定位結構體中的每一個數據區(公司的名稱等),si定位數組項中的每個元素
8.7 div指令
div是除法指令,注意點
1、除數:有8位和16位兩種,在一個reg或內存單元中
2、被除數:默認放在AX或者DX和AX中,如果除數爲8位,被除數爲16位,默認放在AX中存放,如果除數爲16位,被除數則爲32位,在DX和AX中存放,DX存放高16位,AX存放低16位
3、如果除數爲8位,則AL存儲除法操作的商,AH存儲餘數,如果除數爲16位,AX存儲上,DX存儲餘數
格式如下
div reg
div 內存單元
div byte ptr ds:[0] ; (al)=(ax)/((ds)*16+0)的商
; (ah)=(ax)/((ds)*16+0)的餘數
div word ptr es:[0] ; (ax)=((dx)*10000h+(ax))/((es)*16+0)的商
; (dx)=((dx)*10000h+(ax))/((es)*16+0)的餘數
實例
利用除法指令計算100001/100
100001>65535,用dx和ax聯合存放,被除數是32位,所以即使除數100可以在8位寄存器中存放,但是需要用16位的寄存器保存
10001 = 186A1H,所以DX=0001H AX=86A1H
mov dx,1
mov ax,86A1H ; (dx) *10000H+(ax) = 100001
mov bx,100
div bx
執行後 (ax)=03E8H (dx)=1
利用除法指令計算1001/100
mov ax,1001
mov bl,100
div bl
8.8 僞指令dd
用dd定義雙字型數據
data segement
db 1
dw 1
dd 1
data ends
data:3處爲00000001H
用div計算data段中第一個數據除以第二個數據後的結果,商存在第三個數據的存儲單元中
data segment
dd 100001
dw 100
dw 0
data ends
第一個數據爲雙字型,要用DX和AX聯合存放
mov ax,data
mov ds,ax
mov ax,ds:[0]
mov dx,ds:[2]
div word ptr ds:[4]
mov ds:[6],ax
8.9 dup
和db、dw、dd一樣,dup也是由編譯器處理的符號,並和它們配合使用,進行數據的重複
db 3 dup (0) ; 相當於db 0,0,0
db 3 dup (0,1,2) ; 相當於db 0,1,2,0,1,2,0,1,2
db 3 dup ('abc','ABC') ; 相當於db 'abcABCabcABCabcABC'
dup使用格式
db 重複次數 dup (重複的字節型數據)
dw 重複次數 dup(重複的字型數據)
dd 重複次數 dup(重複的雙字型數據)
定義一共容量爲200個字節的棧段
stack segment
db 200 dup (0)
stack ends