所谓寻址方式, 就是指令中用于说明操 作数所在地或者所在地地址的方法 8088/8086 的寻址方式分为两类 : 关于寻找数据的寻址方式 关于寻找转移地址的寻址方式
下面讲关于数据的寻址方式时, 均以数 据传送指令 MOV 为例讲解 MOV 指令格式如下 : MOV DST, SRC 助记符 目的操作数 指令完成的功能 : (DST) 源操作数 (SRC)
一. 关于寻找数据的寻址方式 ( 共 8 种 ) 数据的寻址方式就是告诉 CPU 存 / 取数据的地方 1. 立即寻址 操作数直接存放在指令中, 紧跟在操作码之后, 作为指令的一部分, 存放在代码段里, 这种操作数称为立即数 立即寻址主要用来给 REG 或 M 赋初值 注意 : 只能用于源操作数字段, 不能用于目的操作数字段 如 :MOV 12H, AL ( 语法错误 )
例 :MOV AX,1234H A X A H A L (AX)=1234H B8H 34H 12H 存储器 CS 段 操作码
2. 寄存器寻址 数据放在指令规定的寄存器中, 对 16 位数据, REG 可以是 AX BX CX DX SI DI SP BP 以及段寄存器, 而对于 8 位数据, REG 可以是 AH AL BH BL CH CL DH DL 在程序设计中, 一般存放数据时, 寄存器选择通用寄存器, 而存放结果时尽可能的使用 AX 累加器, 因为使用 AX 累加器要比用其它寄存器存放结果, 指令执行时间要短一些 寄存器寻址既可以作 DST, 也可以作 SRC
例 :MOV AX, BX A X B X 若 (AX)=1234H,(BX)=5678H, 则 CPU 执行上条指令后,(AX)=5678H, 而 (BX) 不变 又如 :MOV CX, DL ( 语法错误 ) 错误原因 : 类型不一致
3. 存储器寻址 这类寻址方式, 操作数在存储器中, 而存储器单元的地址由以下五种寻址方式的任何一种均可以找到 但在指令中给出的只是要寻找的操作数所在单元的段内偏移地址, 而操作数所在单元的段地址除非指令中用段超越前缀特别指明, 否则是默认的
1 直接寻址 指令中直接给出了要寻找操作数所在单元的 16 位偏移地址 指令中直接给出的操作数所在单元的 16 位偏移地址默认在数据段 也可以通过增加段超越前缀来改变操作数所在的段地址 操作数所在单元的物理地址 : PA= ( 段寄存器 ) 16 + 指令中给出的偏移地址
例 1:MOV AX,[2000H] 若 DS 为 3000H, 则 : DS + 3 0 0 0 0 H 2 0 0 0 H PA=3 2 0 0 0 H A X A H A L 32000H 32001H A1H 00H 20H 存储器 CS 段 操作码 数据段
存储器 3.6 8086/8088 的寻址方式 例 2:MOV [2000H],AL 若 DS 为 3000H, 则 : DS + 3 0 0 0 0 H 2 0 0 0 H PA=3 2 0 0 0 H A L 32000H 00H 20H CS 段 操作码 数据段
存储器 3.6 8086/8088 的寻址方式 例 3:MOV ES:[2000H],AL 若 ES 为 2050H, 则 : ES + 2 0 5 0 0 H 2 0 0 0 H PA=2 2 5 0 0 H A L 22500H 00H 20H 前缀码操作码 CS 段附加数据段
在实际的汇编语言程序设计中, 如果程序比较复杂, 而用到的存放数据的单元又很多, 那么在直接寻址方式当中, 用户就要记住存放数据的每个单元的地址, 同时还要记住该地址单元存放的数据的意义, 这样对设计程序带来了很大的困难 所以在实际的汇编语言程序设计中, 常常采用给存放数据的单元, 定义一个符号地址名, 即变量名 / 变量
变量名一但定义了, 就具有了 : 该单元的段地址该单元的偏移地址类型长度 五个属性 大小 这样, 在程序设计中就可以用这个变量名代替原来的存储器单元的实际地址
例 4: 若 (DS)=1500H,TABLE 为在 DS 段定义的一个字变量, 且偏移地址为 0004H 则 CPU 执行 MOV AX,TABLE 指令完成的操作如下 : DS + 1 5 0 0 0 H 0 0 0 4 H PA=1 5 0 0 4 H A H A L 15004H 15005H 存储器 TABLE 数据段
例 5: 若 VAR1 为字变量, VAR2 和 VAR3 为字节变量, 判断下列指令的书写格式是否正确, 正确的说出 SRC 和 DST 的寻址方式, 不正确说出错误原因 MOV AX, VAR1 SRC 为直接寻址 DST 为寄存器寻址 MOV AX, VAR2 类型不一致 MOV VAR2, VAR3 两存储器单元之间不能直接传送数据 MOV [0200H],12H 类型不明确
例 6: 将例 5 中语法不正确的语句改对 MOV AX, VAR2 类型不一致改 :MOV AL, VAR2 MOV VAR2, VAR3 两存储器单元之间不改 :MOV AL,VAR3 能直接传送数据 MOV VAR2,AL MOV [0200H],12H 类型不明确改 :MOV BYTE PTR [0200H],12H 或者 :MOV WORD PTR [0200H],12H 注 :PTR 为临时属性修改符
2 寄存器间接寻址 这种寻址方式, 要寻找的操作数在某存储器单元中, 该存储器单元地址的段内 16 位偏移地址在指令中以 BX SI DI 某一个寄存器给出 其段地址默认在 DS 段 EA= BX SI DI
例 1:MOV AX, [BX] 其 SRC 为寄存器间接寻址 ; DST 为寄存器寻址 ; 指令完成的功能为 : AX (DS:(BX)) 若 :DS=3000H, BX=1050H 则 :SRC 所在单元的物理地址为 : PA=(DS) 16+(BX) =30000H+1050H =31050H
DS: 3 0 0 0 0 H + BX: 1 0 5 0 H PA: 3 1 0 5 0 H A H A X A L 31050H 31051H 8BH 07H 存储器 CS 段 操作码 数据段
例 2:MOV ES:[SI], AL 指令完成的功能为 : (ES:(SI)) (AL) 若 :ES=4000H, SI=1234H,(AL)=23H 则 :DST 所在单元的物理地址为 : PA=(ES) 16+(SI) =40000H+1234H =41234H 指令执行后 (41234H)=23H.
例 3: 判断下列指令的书写格式是否正确, 正确的说出 SRC 和 DST 的寻址方式, 不正确说出错误原因, 并改正 1 MOV [BX], [SI] 两存储器单元之间不 改正 :MOV AL, [SI] MOV [BX], AL 能直接传送数据 ; 类型也 不明确
2 MOV [DI],12H 类型不明确 改正 :MOV WORD PTR [DI], 12H 3 MOV [SI],CX DST 为寄存器间接寻址 SRC 为寄存器寻址
3 寄存器相对寻址 要寻找的操作数在某存储器单元之中, 该单元 的有效地址的一部分在 8 位个 DISP 16 位 BX BP SI DI 中, 另一部分为一 其中,DISP 相对位移量
BX BP SI DI EA= + 8 位 DISP 16 位 DISP 在 DISP 为常数时, 操作数所在单元的段地址以寄存器为准, 若寄存器为 BX SI DI, 操作数默认在 DS 段中 若寄存器为 BP, 操作数默认在 SS 段中 在 DISP 为变量时, 操作数所在单元的段地址以变量为准, 变量在哪个段定义的, 就取该段的段地址
例 1:MOV AX, [BX]+05H 其中,SRC 也可以写成 : [BX+05H] 05H[BX] 05H+[BX] 若 :DS=2000H, BX=0008H, 存放操作数单元的物理地址为 : PA=(DS) 16+(BX)+05H =20000H+0008H+05H =2000DH
AX + 2 0 0 0 0 H 0 0 0 8 H 0 0 0 5 H 2 0 0 0 D H A H A L 2000DH 2000EH 8BH 47H 05H 操作码 数据段 CS 段 存储器
例 2:MOV AX, [BP] 若 :SS=1050H, BP=0050H, 存放操作数的存储单元的物理地址为 : PA=(SS) 16+(BP)+00H =10500H+0050H+00H =10550H
+ 1 0 5 0 0 H 0 0 5 0 H 1 0 5 5 0 H 相对偏移量 DISP 为 0, 这里特别指出,BP 寄存器无间接寻址, 只不过再相对寻址时,DISP 为 0 A H A L 10550H 10551H 操作码 SS 段 CS 段 存储器
例 3: 若 (DS)=1500H,TABLE 为在 DS 段定义的一个字变量, 且偏移地址为 0004H,(BP)=0003H MOV AX,TABLE [BP] SRC 的寻址方式为寄存器相对寻址 指令完成的操作为 : (AX) (DS: OFFSET TABLE+(BP))
4 基址变址寻址 要寻找的操作数在某存储器单元之中, 该单元 有效地址的一部分在中 BX BP BX EA= + BP 中, 另一部分在 SI DI SI DI 该单元的段地址以基址寄存器为准, 若基址寄存器为 BX, 则段地址默认在 DS 中, 若基址寄存器为 BP, 则段地址默认在 SS 中
例 1:MOV AX, [BX][SI] (AX) (DS:(BX+SI)) 例 2:MOV AX, [BP][SI] (AX) (SS:(BX+SI)) 例 3:MOV [BP][DI], AL (SS:(BX+DI)) (AL)
5 基址 变址相对寻址 它是基址变址寻址的扩充, 操作数仍在存储器中, 存储器单元的有效地址为 : BX 8 位 DISP EA= + SI + BP DI 16 位 DISP 同样, 如果用 BX 作为基地址, 操作数默认在 DS 段中 ; 如果用 BP 作为基地址, 则在 SS 段中 在 DISP 为变量时, 操作数所在单元的段地址以变量为准, 变量在哪个段定义的, 就取该段的段地址
例 1: MOV AX, [BX][DI]04 (AX) (DS:(BX+DI+04H)) 例 2:MOV AX, [BP][DI]04 (AX) (SS:(BX+DI+04H)) 例 3:MOV DS:[BP][DI]+04H, AL (DS:(BX+DI+04H)) (AL)
8. 隐含寻址 有些指令的指令码中不包含指明操作数地址的部分, 而其操作码本身隐含的指明了操作数地址 如 : 乘除法指令 字符串操作类指令等
例 1. 若 (BX)=0158H, (DI)=10A5H, (DS)=2100H, DISP=1B57H, (BP)=0100H, (SS)=1100H, 段寄存器按默认段寄存器, 则相对于各种寻址方式的 EA 的求法如下 : 直接寻址 : EA=1B57H PA=21000H+1B57H=22B57H
例 1. 若 (BX)=0158H, (DI)=10A5H, (DS)=2100H, DISP=1B57H, (BP)=0100H, (SS)=1100H, 段寄存器按默认段寄存器, 则相对于各种寻址方式的 EA 的求法如下 : 寄存器间接寻址 ( 设寄存器为 BX): EA=0158H PA=21000H+0158H=21158H
例 1. 若 (BX)=0158H, (DI)=10A5H, (DS)=2100H, DISP=1B57H, (BP)=0100H, (SS)=1100H, 段寄存器按默认段寄存器, 则相对于各种寻址方式的 EA 的求法如下 : 寄存器相对寻址 ( 以 BP 为例 ): EA=0100H+1B57H=1C57H PA=11000H+1C57H =12C57H
例 1. 若 (BX)=0158H, (DI)=10A5H, (DS)=2100H, DISP=1B57H, (BP)=0100H, (SS)=1100H, 段寄存器按默认段寄存器, 则相对于各种寻址方式的 EA 的求法如下 : 基址变址寻址 (BX DI): EA=0158H+10A5H=11FDH PA=21000H+11FDH=221FDH
例 1. 若 (BX)=0158H, (DI)=10A5H, (DS)=2100H, DISP=1B57H, (BP)=0100H, (SS)=1100H, 段寄存器按默认段寄存器, 则相对于各种寻址方式的 EA 的求法如下 : 基址变址相对寻址 (BP DI): EA=0100H+10A5H+1B57H=2CFCH PA=11000H+2CFCH=13CFCH
例 2: 判断下列指令的书写格式是否正确, 正确的说出 SRC 和 DST 的寻址方式, 不正确说出错误原因 MOV AX, [BX][SI] SRC 为基址变址寻址 DST 为寄存器寻址 MOV AX, BL 类型不一致 MOV [BP], [DI+01H] 两存储器单元之间不能直接传送数据 MOV [BX][DI]+02H,12H 类型不明确
作业 :P61-P62 1. 2. 3. 4. 5. 6. 7.(1) (3) 8.(2) 9. 10. 11.
二. 说明转移地址的寻址方式 寻找的操作数作地址用, 给 IP 或给 CS:IP, 从而实现程序的转移 如果程序转移后只有 IP 发生了改变, 则称为段内转移或者称为近程转移 ( 也称为 NEAR 型转移 ) 如果程序转移后 CS IP 均发生了改变, 则称为段间转移或者称为远程转移 ( 也称为 FAR 型转移 )
8086 指令系统中的转移指令有两大类 : 无条件转移指令 : 有 JMP CALL RET IRET 条件转移指令 : 如 JZ JC JCXZ LOOP 等 段内转移地址的寻址方式 ( 只有 IP 发生改变 ) 1. 段内直接寻址 ( 也叫段内相对寻址 ) 这种寻址方式中, 指令中直接写出了转移目的地的符号地址 (NEAR 型标号名 )
操作码 8 为 DISP XXH 当前 IP -128??H +127 JMP SHORT L1 L1: 间隔的字节数称为相对位移量 DISP 转移目的地的 IP= 当前 (IP)+8 位 DISP
16 位 DISP XXH 操作码??H -32768 当前 IP??H +32767 L1: JMP L1 ;JMP NEAR PTR L1 间隔的字节数称为相对位移量 DISP 转移目的地的 IP= 当前 (IP)+16 位 DISP
指令中指明的 8bit/16bit 的相对位移量 DISP 是相对于当前 IP 来计算的, 有正 负转移, 向地址增加的方向转移, 为正转移,DISP 用原码表示 ; 向地址减小的方向转移, 为负转移,DISP 用补码表示 转移目的地物理地址的求法 : PA=(CS) 16+ 当前 (IP)+DISP 注 :8086 指令系统当中的所有条件转移指令只能在段内转移, 且转移范围以当前 IP 为基准, 不能超出 -128 +127 之间, 其寻址方式为段内相对寻址
2. 段内间接寻址 这种寻址方式中, 转移地址的段内偏移地址要么存放在一个 16bit 的寄存器中, 要么放在存储器的一个字单元之中 这个寄存器或字单元的地址, 由前面讲过的数据的寻址方式指明 只不过寻址所得到的不是数据, 而是偏移地址
例 : 若 (DS)=2000H,(BX)=0100H,(SI)=0002H, (20100H)=1200H,(20102H)=1250H, 则 CPU 执行 : JMP BX 指令后,(IP)=0100H JMP WORD PTR [BX] 指令后,(IP)=1200H JMP WORD PTR [BX][SI] 指令后,(IP)=1250H
段间转移地址的寻址方式 (CS IP 均发生改变 ) 只适合于无条件转移指令 1. 段间直接寻址 指令语句书写时直接写出转移目的地的符号地址 (FAR 型标号名 ) 书写格式为 : JMP FAR PTR 标号名
XXH 操作码 SEG ADDR **H **H OFFSET ADDR ;????:****H??H??H JMP FAR PTR ADDR ADDR: 代码段 2 代码段 1
存储器 3.6 8086/8088 的寻址方式 如 :JMP FAR PTP ADDR CS + 4 0 0 0 H IP3 0 0 0 H 4 3 0 0 0 H 操作码 OFFSET 低字节 OFFSET 高字节 SEG 低字节 SEG 高字节 00 30 00 40 IP CS ADDR OP CODE
2. 段间间接寻址 这种寻址方式和段内间接寻址方式相似, 但不可能有寄存器间接寻址了, 因为要得到的转移地址是 32bit(16bit SEG 地址和 16bit EA 地址 ) 因此转移目的地的地址只能间接的存放在一个双字的存储器单元当中 这个双字存储器单元可以用五种存储器寻址方式的任一种寻找到 找到的这个双字单元 ( 连续的 4 个字节单元 ) 存放的就是转移地址如下图所示 :
存放转移地址的首址 低字节 高字节 低字节 高字节 存储器 转移 OFFSET IP 转移 SEG 地址 CS
如 :JMP DWORD PTR [BX][DI] 若 (DS)=3000H,(BX)=1000H, (DI)=2000H, 则 : DS: 3 0 0 0 BX: 1 0 0 0 DI: + 2 0 0 0 3 3 0 0 0 H CS: 8 0 0 0 IP: + 2 0 0 0 8 2 0 0 0 H 33000H 82000H 05H 00H 20H 00H 80H OP CODE IP CS
小 结 一. 8086 寻址方式 寻找数据 寻找地址 立即数寻址直接寻址寄存器寻址寄存器间接寻址存储器寻址寄存器相对寻址基址变址寻址隐含寻址基址变址且相对寻址段内直接寻址 ( 相对寻址 ) 间接寻址直接寻址段间间接寻址
小 结 二. 8086 指令系统当中的所有条件转移指令只能在段内转移, 且转移范围以当前 IP 为基准, 不能超出 -128 +127 之间, 其寻址方式为段内相对寻址 作业 : 12. 13.