8086寻址方式
寻址方式总共有两大类:
按数据寻址
按地址寻址
1.数据寻址方式
MOV DST,SRC
-
和数据有关的寻址方式
1.立即寻址:
-
操作数直接在源操作数中给出
MOV AL,45H
源操作数在指令中给出,立即数只能是源操作数
立即数的长度和DST长度一致
2.寄存器寻址
-
操作数放在指定的寄存器中
MOV AX,BX
MOV AL,BH
MOV AX,DX
字节寄存器只有:AH,AL,BH,BL,CH,CL,DH,DL
字寄存器有:AX,BX,CX,DX,SI,DI,BP,SP,CS,ES,DS,SS等
CS不能用MOV指令改变,CS是代码段的寄存器
3.直接寻址
-
有效地址(偏移地址EA由指令直接给出)
源操作数有两种形式:
MOV AX,[1200H]
MOV AX,VALUE ;VALUE是字类型的变量,变量的类型要与目的操作数的类型一致
可以使用段跨越前缀 MOV AX,ES:[2000H]
4.寄存器间接寻址
-
EA在基址寄存器(BX/BP)或变址寄存器(SI/DI)中
MOV AX,[BX] ;PA = (DS)*16+(BX)
MOV AX,ES:[BX] ;PA = (ES)*16+(BX)
MOV AX,[BP] ;PA = (DS)*16+(BP)
寄存器间址只能用这四个寄存器,不能使用别的寄存器
适用于:数组,字符串,表格的处理
5.寄存器相对寻址
-
EA = 间址寄存器(BX,BP,SI,DI)内容 + 8/16位偏移量(一般用标号表示)
MOV AX,COUNT[SI] 或者
MOV AX,[COUNT+SI]
;COUNT是固定的,SI相当于可变的下标,可以用来遍历数组,串,表格
6.基址变址寻址
-
EX = 基址寄存器(BX/BP)+变址寄存器(SI/DI)
MOV AX,[BX+DI] 或者
MOV AX,[BX] [DI] 或者
MOV AX,ES:[BX] [SI]
适用于数组,串,表格处理
必须是一个基址寄存器和一个变址寄存器的结合
基址寄存器存起始地址,变址寄存器存可变的偏移量
7.相对基址变址寻址
-
EA = 基址寄存器 + 变址寄存器 + 8/16位偏移量
MOV AX,MASK[BX] [ SI] 或者
MOV AX,MASK[BX+SI] 或者
MOV AX,[MASK+BX+SI]
偏移量一般用变量名表示,
处理表格
数据寻址方式练习:
-
编写一段显示字符串STRING的程序-- DOS 2号功能调用只能给DL传递寄存器中的值,或者字符,ASCII,不能从内存中取
1.寄存器间接寻址访问数据
DATA SEGMENT STR DB 'HAPPY NEW YEAR',0AH,0DH,'$' DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV BX,OFFSET STR MOV CX,17 NEXT: MOV DL,[BX] MOV AH,02H INT 21H INC BX LOOP NEXT MOV AH,4CH INT 21H CODE ENDS END START
2.寄存器相对寻址方式访问数据
;声明数据段 DATA SEGMENT STRING DB 'HAPPY NEW YEAR!',0AH,0DH,'$' COUNT DW 17 ;STRING串的长度,$表示字符串结束的标志 DATA ENDS ;声明代码段,数据段 CODE SEGMENT ASSUME CS:CODE,DS:DATA ;绑定代码段和数据段到指定段寄存器 START: MOV AX,DATA MOV DS,AX ;这两句是把DATA初始地址放到DS中,代表数据段定义结束 ; 寄存器相对寻址+循环 MOV CX,COUNT ;设置循环次数,CX用来保存循环的次数,和LOOP一起使用 MOV SI,OFFSET STRING ;保存STRING的偏移地址,用来做串的下标,可变 ; 2号功能调用输出字符,SRC为字符的ASCII形式或者字符形式('A'),一次只能输出一个字符 PRINT: MOV DL,STRING[SI] MOV AH,2 INT 21H INC SI ;SI++,用来遍历STRING LOOP PRINT ;LOOP指令执行分两步,_1.(CX)=(CX)-1,_2.判断CX中的值,不为0则跳转到标号处执行程序,如果为0,则跳出循环向下顺序执行程序 CODE ENDS ;代码段结束 END START
3.相对基址变址寻址
;声明数据段 DATA SEGMENT STRING DB 'HAPPY NEW YEAR!',0AH,0DH,'$' COUNT DW 17 ;STRING串的长度,$表示字符串结束的标志 DATA ENDS ;声明代码段,数据段 CODE SEGMENT ASSUME CS:CODE,DS:DATA ;绑定代码段和数据段到指定段寄存器,仅仅是声明,真正情况是CS系统自动绑定,ds,es,ss要用户自己手动写代码绑定 START: ; 让DATA指向DS数据段 MOV AX,DATA MOV DS,AX ;这两句是把DATA初始地址放到DS中,代表数据段定义结束 ; 寄存器相对寻址+循环 MOV CX,COUNT ;设置循环次数,CX用来保存循环的次数,和LOOP一起使用 MOV BX,0 ;数组是一维空间的所以基址变址寄存器中只要一个变就行了 MOV SI,OFFSET STRING ;保存STRING的偏地址,用来做串的下标,可变 ; 2号功能调用输出字符,SRC为字符的ASCII形式或者字符形式('A'),一次只能输出一个字符 PRINT: MOV DL,STRING[BX][SI] MOV AH,2 INT 21H INC SI ;SI++,用来遍历STRING LOOP PRINT ;LOOP指令执行分两步,_1.(CX)=(CX)-1,_2.判断CX中的值,不为0则跳转到标号处执行程序,如果为0,则跳出循环向下顺序执行程序 ;DOS是一个单用户单任务的OS,每次只能运行一个程序,运行完一个程序必须返回OS控制权给OS,不使用该语句,该程序会永远停留再这里,OS无法继续运行 MOV AH,4CH INT 21H CODE ENDS ;代码段结束 END START ;END表示汇编结束
-
2.和地址有关的寻址方式 — 用来确定转移指令及CALL指令的转向地址
段内寻址
- 段内直接寻址 JMP NEAR PATR NEXT
- 段内间接寻址 JMP TABLE[BX]
段间寻址
- 段间直接寻址 JMP FAR PTR NEXT
- 段间间接寻址 JMP DWORD PTR [BX]
3.段寄存器的使用规定