微机原理与系统设计篇8086寻址方式
今天由于做核酸,错过了老师的课程,晚上就来浅浅总结一下吧。会结合汇编指令,进行举例介绍。
寻址方式
汇编指令格式: 指令码 目的操作数,源操作数
数据寻址方式
立即寻址
表示在汇编指令当中,直接指定数据,即指令当中源操作数是一个具体的值。例如MOV AX 1200H
表示将1200H分别赋给寄存器AX的高位和低位当中。
寄存器寻址
寄存器寻址的特点是,操作数是CPU内部的寄存器,分为16位操作和8位操作
- 16位寄存器有数据寄存器 AX/BX/CX/DX,和地址指针寄存器SP/BP/SI/DI,
MOV AX,SP
- 8位寄存器有数据寄存器AH,AL,等
MOV DL,AH
,寄存器寻址不需要读取存储器内容,因此寻址速度较快。
存储器寻址
我们知道存储器的地址是20位,其中包括高16位的段地址,以及第四位的偏移地址。,存储器寻址的核心在于找到准确的段地址和偏移地址,以便形成完整的物理地址。
直接寻址
- 例如
MOV AX,[2000H]
,其中2000H表示偏移地址,未指定段地址,默认段地址为DS。
这里与立即寻址不同,MOV AX,2000H
,表示将2000H赋给寄存器AX,MOV AX,[2000H]
则表示在存储器里找地址为DS:2000H的存储单元,将存储单元里的值赋给AX。
寄存器间接寻址
- 例如
MOV AX,[SI]
,表示将SI里储存的内容作为偏移地址,默认为DS表示段地址,将DS:[SI]地址的内容赋值给AX。 - 例如
MOV AX,ES:[SI]
,这个属于段超越。在进行8086寻址时,是有一些默认寄存器的操作情况,比如SI默认段地址为DS,这里就可以进行段超越,指定段地址为ES。
这里罗列出默认段地址:
SI,DI,BX => DS
BP => SS
相对寻址方式
基于之前的默认段地址,我们来讨论相对寻址方式,EA表示有效地址(偏移地址)
即 EA = (BX)或(BP)或(SI)或(DI) + 8位或16位位移量
- 如果引用的是SI,DI,BX作为段地址的话,那么其默认段地址为DS,例如
MOV AX,[DI+2000H]
,表示找到地址为DS:[DI+2000H]的存储单元,将该存储单元中的内容赋值给AX。 - 如果引用的是BP作为偏移地址的,那么默认段地址为SS,例如
MOX AX,[BP-1000H]
,表示找到地址为SS:[BP-1000H]的存储单元,将该存储单元中的内容赋值给AX。 - 也可以直接指定段地址
MOV ES:[BX+5], AL
,表设计将AL中的数值赋给地址为ES:[BX+5]的存储单元种。
基址变址寻址方式
就是使用基址寄存器(BX,BP)与变址寄存器(SI,DI)中的数据,得到有效地址(偏移地址)
即:EA = (BX)或(BP) + (SI)或(DI)
如果说在EA的计算中出现了BP,那么当前偏移地址所对应的段地址为SS,否则为DS。
- 例如
MOV AX, [BX+DI] ; 此时引用DS段寄存器
- 第二种情况
MOV AX, [BP+DI] ; 此时引用SS段寄存器
- 也可以增加段超越来指定段地址
MOV AX, ES:[BX+SI] ; 引用ES作为段寄存器
和MOV DS:[BP+SI], AL ; 引用DS作为段寄存器
基址变址相对寻址方式
即:EA = (BX)或(BP) + (SI)或(DI) + 8位或16位位移量
例如MOV BX,[BP+SI-1230H]
,如果说读懂上上面的代码意义,那么这个也是一样的。将物理地址为SS:[BP+SI-1230H]的存储单元内容给BX。
转移地址寻址方式
段内直接寻址
需要转移到的地址 = 当前IP +(8位或者16位的数)
ADD1:ADD AL,01H; //ADD1/记录下转移地址
JMP ADD1;//跳转到段内转移地址
段内间接寻址
转移地址存放在寄存器或者存贮器当中,寻址的实质是,用保存的地址覆盖当前的指令地址IP
寄存器只能使用BX、BP、DI、SI。但是,这里不能用方括号,而是使用WORD PTR,表示以寄存器值作为地址取数两个字节。
MOV AX,0000H;
MOV CS,AX;
MOV BX,0000H; //二选一//MOV [BX],1000H;//数据的寄存器间接寻址
JMP WORD PTR BX;//程序的间接寻址
段间直接寻址
直接修改段地址和偏移地址来覆盖掉当前的CS:IP。
段间间接寻址
从指令中给出的存储器地址确定四个连续的存储单元地址,用前两个单元内容修改IP,后两个单元内容修改CS
读取4个字节作为CS和IP的值,其中IP获得两个低字节,CS获得两个高字节。下例中,BX保存了VAR1的偏移地址,最终IP获取3344H,CS获取1122H。
MOV BX,OFFSET VAR1;
JMP FAR PTR BX;//程序段间间接寻址
ret
VAR1 DD 11223344H;