2014年4月8日 星期二 23时44分34秒
第八章 数据处理的两个基本问题
(1)计算机处理的数据在什么地方
(2)要处理的数据有多长
寄存器(reg):ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si
段寄存器(sreg):ds,ss,cs,es
8.1 bx,si,di和bp
(1)在8086CPU中,只有这4个寄存器可以用在"[...]"中来进行内存单元的寻址
例如:
mov ax,[bx]
mov ax,[bx+si]
mov ax,[bx+di]
mov ax,[bp]
mov ax,[bp+si]
mov ax,[bp+di]
(2)在[...]中,这4个寄存器可以单个出现,或只能以4中组合出现:bx和si,bx和di,bp和si,bp和di
例如:
mov ax,[bx]
mov ax,[si]
mov ax,[di]
mov ax,[bp]
mov ax,[bx]
mov ax,[bx+si]
mov ax,[bx+di]
mov ax,[bp+si]
mov ax,[bp+di]
mov ax,[bx+si+idata]
mov ax,[bx+di+idata]
mov ax,[bp+si+idata]
mov ax,[bp+di+idata]
下面的指令是错误的:
mov ax,[bx+bp]
mov ax,[si+di]
(3)只要在[...]中使用寄存器bp,而指令中没有显式的给出段地址,段地址默认在ss中。 例如:
mov ax,[bp] 含义:(ax)=((ss) * 16 + (bp))
mov ax,[bp+idata] 含义:(ax)=((ss) * 16 + (bp) + idata)
mov ax,[bp+si] 含义:(ax)=((ss) * 16 + (bp) + (si))
mov ax,[bp+si+idata] 含义:(ax)=((ss) * 16 + (bp) + (si) + idata)
8.2 机器指令处理的数据在什么地方
绝大部分机器指令都是进行数据处理的指令。大致可以分为3类:读取,写入,运算
数据可以存在3个地方:CPU内部,内存,端口
8.3 汇编语言中数据位置的表达
汇编中用3个概念来表达数据的位置:
(1)立即数(idata)
对于直接包含在机器指令中的数据(执行前在CPU的指令缓冲器中),在汇编语言中称为立即数(idata),即在汇编指令中直接给出
例: mov ax, 1
mov ax, 'a'
(2)寄存器
指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名。
例: mov ax,bx
mov ds,ax
(3)段地址(SA)和偏移地址(EA)
例: mov ax,[0]
mov ax,[bx+si]
8.4 寻址方式
定位内存单元的方法我们称之为寻址方式。
8.5 指令要处理的数据有多长
(1)8086CPU的指令,可以处理两种尺寸的数据,即byte和word。即字节和字。
(2)在没有寄存器名存在的情况下用操作符X ptr指明内存单元的长度。X在汇编中可以为word或byte
例如:下面的指令中,用word ptr指明了指令访问的内存单元是一个字单元
mov word ptr ds:[0],1
inc word ptr [bx]
add word ptr [bx],2
例如:下面的指令中,用btye ptr指明了指令访问的内存单元是一个字节单元
mov byte ptr ds:[0],1
在没有寄存器参与的内存单元访问指令中,用word ptr 或byte ptr显性的指明要访问的内存单元的长度是很有必要的。
(3) 其他方法
有些指令默认访问的是字单元或字节单元。
例如:push [1000H]就不能指明访问的是字单元还是字节单元,因为push指令只进行字操作
8.6 寻址方式的综合应用
;寻址方式的综合应用
assume cs:code
code segment
start:mov ax,seg
mov ds,ax
mov bx,60h
mov word ptr [bx+och],38
add word ptr [bx+oeh],70
mov si,0
mov word byte [bx+si+10h],'V'
inc si
mov word byte [bx+si+10h],'A'
inc si
mov word byte [bx+si+10h],'X'
code ends
end start
8.7 div指令
div是除法指令,使用div做除法时应注意以下几个问题:
(1)除数:有8位和16位,在一个reg或内存单元中
(2)被除数:默认放在AX或DX和AX中,如果除数为8位,被除数则为16位,默认在AX中存放;
如果除数为16为,被除数则为32为,在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转换为16进制为186A1H. 因为100001大于2的16次方(65536),所以被除数采用32位的计数器进行计算。高位存在dx,低位存在ax中
;100(64H)小于2的8次方,所以采用8位的寄存器就可以,但是被除数是32位,所以这边必须采用16的寄存器。
;则ax存放商,dx存放余数
assume cs:code
code segment
start:
mov dx,1
mov ax,86A1h
mov bx,100
div bx
mov ax,4c00h
int 21h
code ends
end start
----------------------------------------
;编程,利用除法指令计算1001/100
;1001(3E9H)小于2的16次方大于2的8次方,故被除数采用16位的寄存器。(默认在AX中)
;100小于2的8次方,故除数采用8位寄存器
;AL为商,AH为余数
;结果 AX=010A
assume cs:code
code segment
start:
mov ax,1001
mov bl,100
div bl
mov ax,4c00h
int 21h
code ends
end start
问题:问什么有时候要将被除数转换为16进制,有时候又不需要呢?
8.8 伪指令dd
dd: define double word 定义双字型数据
;问题8.1
;用div计算data段中第一个数据除以第二个数据的结果,商存在第三个数据的存储单元中
assume cs:code,ds:data
data segment
dd 100001
dw 100
dw 0
data ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,ds:[0] ;低16位存储在ax中
mov dx,ds:[2] ;高16位存储在dx中
div word ptr ds:[4]
mov ds:[6],ax ;将商存在ax:[6]中
mov ax,4c00h
int 21h
code ends
end start
8.9 dup
dup是一个操作符,在汇编汇中同db,dw,dd等一样,也是由编译器识别的符号。 它和db,dw,dd等伪指令配合使用,用来进行数据的重复。
db 3 dup (0,1,2) 即定义了9个字节,他们是0,1,2,0,1,2,0,1,2
db 重复的次数 dup (重复的字节型数据)
dw 重复的次数 dup (重复的字型数据)
dd 重复的次数 dup (重复的双节型数据)
;定义容量为100个字节的栈
;用dup
stack segment
dd 200 dup (0)
stack ends
实验七 寻址方式在结构化数据访问中的应用
;编程,将data段中的数据按如下格式写入到table段中,并计算21年中人均收入。
assume cs:code, ds:data
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
;以上是表示21年的字符串
dd 16,22,382,1356,2390,8000,16000,24486,50065,97497,140417,1977514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;以上是表示21年公司总收入的21个dword型数据
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
;以上是表示21年公司雇员人数的21个word型数据
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
code segment
start:
mov ax,data
mov ds,ax
mov cx,21
mov si,0
mov di,0
mov ax,table
mov es,ax
s:
mov ax,ds:[si] ;年份转送
mov es:[di],ax
mov ax,ds:[si+2]
mov es:[di+2],ax
mov ax,ds:[84+si] ;收入传送
mov es:[5+di],ax
mov dx,ds:[84+si+2]
mov es:[7+di],dx
push cx
mov cx,ds:[84+84+bx] ;雇员数传送
mov es:[10+di],cx
;计算人均收入
div cx
pop cx
mov es:[0Dh+di],ax
add si,4
add bx,2
add di,16
loop s
mov ax,4c00h
int 21h
code ends
end start
2014-4-13 01:47 记 @sanlihe.xichengqu.beijing