一、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