一、bx、si、di、bp
在8086CPU中,只有bx、si、di、bp这四个寄存器可以通过[……]方式来进行内存单元的寻址;
这四个寄存器可以单独存在,也可以以组合的形式进行寻址,但是bx和bp不能一起使用,si和di不能一起使用,所以即使组合最多也只能两个组合,不会有三个组合在一起的形式,当然可以加个常量:[bx+si+idata];
只要使用bp,而段地址没有显式给出,则默认段地址为ss,而其它三个的默认段地址均为ds。注意是只要使用bp,若bp和si都存在,此时si默认段地址是ds,但是因为bp的存在,这个寻址的段地址仍为ss。
二、机器指令处理的数据在什么地方
一共有三个地方:内存、寄存器、指令缓冲器
mov ax,[0] mov ax,bx mov ax,1
像1这种直接包含在机器指令中的数据成为立即数,执行该指令时它在CPU的指令缓冲区中。
三、寻址方式
1.直接寻址:[2]
2.寄存器间接寻址:[bx]
3.寄存器相对寻址:[si+idata]
4.基址变址寻址:[bp+di]
5.相对基址变址寻址[bp+si+idata]
四、指令要处理的数据有多长
1.通过寄存器名指明要处理的数据长度
2.在没有寄存器名时,可通过word ptr和byte ptr指明内存的长度为字或字节
mov word ptr ds:[0],1
inc byte ptr [bx]
五、div指令
算数表达式:A/B 汇编指令表示:div B
那么A是谁?depengs on B
case B为字节:A=DX AX,即A为32位,DX在高位,AX在低位 计算的结果包括两部分:商在AX中,余数在DX中
case B为字:A=AX,即A为16位 计算的结果也包括两部分:商在AL中,余数在AH中
实例:利用除法计算100001/100
mov ax,86a1h
mov dx,1
mov bx,100
div bx
六、伪指令dd和操作符dup
db-- 字节型数据
dw-字型数据
dd-双字型数据
db 3 dup(0)相当于db 0,0,0,
db 2 dup (0,1,2)相当于db 0,1,2,0,1,2
db 2 dup(‘abc’,‘ABC’)相当于db ‘abcABCabcABC’
七、实例
题目:《汇编语言》第2版 王爽 第8章实验7
assume cs:code,ds:data,ds:table,ss:stack
;?????这里的cs,ds有什么用?可以重复使用吗?
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985'
db '1986','1987','1988','1989','1990','1991','1992','1993','1994','1995'
;以上是表示21年的21个字符串
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3573000,4649000,5937000
;以上是21年的公司总收入
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
;以上是21年公司雇员人数
data ends
table segment
db 21 dup('year summ mm ?? ') ;这里需要21行,没行都占用16个字节
table ends
stack segment
db 16 dup(0)
stack ends
code segment
start: mov ax,data
mov ds,ax ;将data数据段段地址赋给段寄存器ds
mov ax,table
mov es,ax ;将table数据段段地址赋给段寄存器es
mov ax,stack
mov ss,ax
mov sp,10h ;初始化栈的段地址和栈顶
;开始复制表示年的字符串
mov cx,21 ;外层循环次数为21
mov si,0 ;ds:[si]来表示data段数据,从[0]开始
mov bx,0 ;es:[bx][di]来表示table段数据,bx=bx+16,di=di+1 di从0到3
s0: push cx ;通过栈保存外层计数器cx
mov cx,4 ;内层循环次数为4
mov di,0 ;di需要每次都需置零
s1: mov al,[si] ;从data段按字节读取数据
mov es:[bx][di],al ;将数据从data段复制到table段,按字节复制
inc di ;talbe段读取下一个字节
inc si ;data段读取下一个字节
loop s1
pop cx ;恢复外层循环次数
add bx,16
loop s0
;结束复制表示年的字符串
;开始复制公司总收入
mov cx,21 ;外层循环次数为21
;mov si,0 ;ds:[si]来表示data段数据
mov bx,5 ;es:[bx][di]来表示table段数据,bx=bx+16,di=di+1 di从0到3
s2: push cx ;通过栈保存外层计数器cx
mov cx,2 ;内层循环次数为4
mov di,0 ;di需要每次都需置零
s3: mov ax,[si] ;从data段按字节读取数据
mov es:[bx][di],ax ;将数据从data段复制到table段,按字节复制
add di,2 ;talbe段读取下一个字节
add si,2 ;data段读取下一个字节
loop s3
pop cx ;恢复外层循环次数
add bx,16
loop s2
;结束复制公司总收入
;开始复制雇员人数
mov cx,21 ;外层循环次数为21
mov bx,10 ;es:[bx][di]来表示table段数据,bx=bx+16,di=di+1 di从0到3
s4: mov ax,[si]
mov es:[bx],ax
add si,2
add bx,16
loop s4
;结束复制雇员人数
;开始计算人均收入
;被除数:es:[bx+5]--[bx+8]
;除数:es:[bx+10]--[bx+11]
;商:es:[bx+13]--[bx+14]
;bx=0,bx=bx+16
mov cx,21 ;外层循环次数为21
mov bx,0
s5: mov ax,es:[bx+5]
mov dx,es:[bx+7]
div word ptr es:[bx+10]
mov es:[bx+13],ax
add bx,16
loop s5
;结束计算人均收入
;要复制dd型数据,也就是4个字节,可以按字复制,也可以按字节复制,这里采用按字复制
mov ax,4c00h
int 21h
code ends
end start
;copy form ds:[bp][si] to es:[bx][di]
;for year: si between 0 and 3,di between 0 and 3,bp = bp + 4,
;for destination: bx=bx+16, di from 0 to 3, from 5 to 8, from 10 to 11. from 13 to 14
;for source:
;0--3, 84--87, 168--169
;4--7, 88--91, 170--171
;4*i+0:4*i+3,
;4*i+84,i*4+87
;2*i+168,2*i+169