定义描述性符号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
这些数据在内存中的存储如图
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