指令系统的寻址方式
指令系统的寻址方式是指计算机处理器在执行指令时,如何定位并访问指令中操作数所在的内存地址或寄存器(寻址方式:获取操作数所在地址的方法)
指令中的操作数
通常一条指令包含操作符和操作数,操作数是指令执行的参与者,也就是说操作数是参与某种功能操作的数据(操作符是加工的方式,操作数是被加工的东西)
提供操作数的三种方式
-
立即数
(参考:什么是立即操作数?)
立刻数是一个常量,可以写成十进制(D),十六进制(H),八进制(O),二进制(B)
assemblyMOV AX,0FFFH ;其中的 0FFFH 就是立即数 ;这条指令的意思是将十六进制值0FFFH加载到AX寄存器中
立即操作数:操作数包含在指令中,它作为指令的一部分 ,跟在操作码后存放在代码段,指令要操作的数据以常量的形式出现在指令中
注意:立即数只能作为源操作数,不能放在目的操作数位置(指令中结果所存放的数据位)
-
寄存器操作数(寄存器存放的数据)
assemblyMOV SI,AX ;这条指令的意思是将AX中的内容复制到SI中
寄存器操作数:指令要操作的数据存放在CPU中的寄存器里,指令中给出寄存器名即可
-
存储器操作数(内存中的数据)
存储器操作数:指令要操作的数据存放在内存某些单元中,指令中给出内存单元物理地址(实际上指令只给出了偏移地址,段地址采用隐含方式给出,也可以使用跨段方式指出当前段地址)
七种寻址方式
立即寻址方式
(对应上文中的立即数)
在立即寻址方式中,操作数的值直接嵌入到指令中,因此在执行指令时无需额外的内存访问或寄存器读取(操作数在指令中)
立即数可以是8位、16位或32位,该数值紧跟在操作码之后。如果立即数为16位或32位,那么,它将按"高高低低"的原则进行存储
assembly
MOV AH, 80H ADD AX, 1234H MOV ECX, 123456H
MOV B1, 12H MOV W1, 3456H ADD D1, 32123456H
;B1、W1 和 D1 分别是字节、字和双字单元
立即数寻址方式通常用于对通用寄存器或内存单元赋初值
寄存器寻址方式
(对应上文的寄存器操作数)
指令所要的操作数已存储在某寄存器中,或把目标操作数存入寄存器。把在指令中指出所使用寄存器(即:寄存器的助忆符)的寻址方式称为寄存器寻址方式(操作数在寄存器中)
assembly
MOV EAX, EBX MOV AX, BX MOV DH, BL
由于指令所需的操作数已存储在寄存器中,在指令执行过程中,会减少读存储器单元的次数,所以,使用寄存器寻址方式的指令具有较快的执行速度
直接寻址方式
指令所要的操作数存放在内存中,在指令中直接给出该操作数的有效地址,这种寻址方式为直接寻址方式(EA在指令中 )
(EA:有效地址,是指操作数的实际存储地址,它是由指令中的地址计算得出的)
assembly
MOV BX, [1234H]
;1234H是一个直接地址,它紧跟在指令的操作码之后,随取指令而被读出
;默认的访问数据段的段寄存器是DS,所以,用DS的值和偏移量1234H相加,得存储单元的物理地址
;取物理地址的值,并按"高高低低"的原则存入寄存器BX中
由于数据段的段寄存器默认为DS,如果要指定访问其它段内的数据,可在指令中用段前缀的方式显式地书写出来
assembly
MOV AX,ES:[1000H]
注意:
-
立即寻址方式和直接寻址方式的书写格式的不同,直接寻址的地址要写在"[]"内
assemblyMOV AX, 1234H MOV AX, [1234H] ;前者是立即寻址,后者是直接寻址
-
直接地址通常用内存变量名来表示
assemblyMOV AX, VARW MOV AX, [VARW] ;VARW是内存字变量 ;两者是等效的,均为直接寻址
MOV BX, VARW,其中,VARW是内存字变量
寄存器间接寻址
操作数在存储器中,操作数的有效地址用SI、DI、BX和BP等四个寄存器之一来指定,称这种寻址方式为寄存器间接寻址方式(EA在BX/BP/SI/DI中 )
(只有这四个寄存器可以作为偏移量)
在不使用段超越前缀的情况下,有下列规定
-
若有效地址用SI、DI和BX等之一来指定,则其缺省的段寄存器为DS
assemblyMOV AX, [BX]
在执行本例指令时,寄存器BX的值不是操作数,而是操作数的地址。该操作数的物理地址应由DS和BX的值形成: P A = ( D S ) ∗ 16 + B X PA=(DS)*16+BX PA=(DS)∗16+BX
-
若有效地址用BP来指定,则其缺省的段寄存器为SS(即:堆栈段)
寄存器相对寻址
操作数在存储器中,其有效地址是一个基址寄存器(BX、BP)或变址寄存器(SI、DI)的内容和指令中的8位/16位偏移量之和(EA为BX/BP/SI/DI加上某个常数)
在不使用段超越前缀的情况下,有下列规定
-
若有效地址用SI、DI和BX等之一来指定,则其缺省的段寄存器为DS
在计算有效地址时,如果偏移量是8位,则进行符号扩展成16位,当所得的有效地址超过0FFFFH,则取其64K的模
assemblyMOV BX, [SI+100H]
在执行本例指令时,源操作数的有效地址EA为: E A = ( S I ) + 100 H EA=(SI)+100H EA=(SI)+100H
该操作数的物理地址应由DS和EA的值形成: P A = ( D S ) ∗ 16 + E A PA=(DS)*16+EA PA=(DS)∗16+EA
-
若有效地址用BP来指定,则其缺省的段寄存器为SS
基址变址寻址
操作数在存储器中,其有效地址是一个基址寄存器(BX、BP)和一个变址寄存器(SI、DI)的内容之和(EA为基址寄存器和变址寄存器内容之和)
在不使用段超越前缀的情况下规定:如果有效地址中含有BP,则缺省的段寄存器为SS;否则,缺省的段寄存器为DS
assembly
MOV BX, [BX+SI]
在执行本例指令时,源操作数的有效地址EA为: E A = ( B X ) + ( S I ) EA=(BX)+(SI) EA=(BX)+(SI)
该操作数的物理地址应由DS和EA的值形成: P A = ( D S ) ∗ 16 + E A PA=(DS)*16+EA PA=(DS)∗16+EA
相对基址变址寻址
操作数在存储器中,其有效地址是一个基址寄存器(BX、BP)的值、一个变址寄存器(SI、DI)的值和指令中的8位/16位偏移量之和(EA为基址寄存器和变址寄存器和某个常数之和)
在不使用段超越前缀的情况下规定:如果有效地址中含有BP,则其缺省的段寄存器为SS;否则,其缺省的段寄存器为DS
assembly
MOV AX, [BX+SI+200H]
MOV AX, 200H[BX+SI]
MOV AX, 200H[BX][SI]
MOV AX, 200H[SI][BX]
;以上几种书写格式都是正确的,并且其寻址含义也是一致
;但书写格式BX[1000+SI]和SI[1000H+BX]等是错误的,即所用寄存器不能在"[]"之外
在执行本例指令时,源操作数的有效地址EA为: E A = ( B X ) + ( S I ) + 200 H EA=(BX)+(SI)+200H EA=(BX)+(SI)+200H
该操作数的物理地址应由DS和EA的值形成: P A = ( D S ) ∗ 16 + E A PA=(DS)*16+EA PA=(DS)∗16+EA
参考文章