Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1675143
  • 博文数量: 20
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 3272
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-04 09:45
文章分类

全部博文(20)

文章存档

2011年(3)

2010年(1)

2009年(1)

2008年(15)

我的朋友

分类:

2009-01-14 09:59:29

操作数采取哪一种寻址方式,会影响机器运行的速度和效率;也影响程序员的程序设计方法。

寻址方式(Addressing)通俗地讲就是寻找地址的方法。

这个地址可以是CPU内部的寄存器――寄存器寻址方式。(程序员以名称区别各个寄存器,但CPU则利用地址编码区别)
这个地址也可以是主存储器地址――存储器寻址方式
这个地址还可以是I/O地址――I/O寻址方式

  • 地址指向的内容可以是程序需要操作的数据,即操作数地址――操作数寻址方式
  • 地址指向的内容可以是程序需要转向的指令,即目标地址――标地址寻址方式


本节学习8086的操作数寻址方式,其他寻址方式在第2章陆续展开。
操作数寻址方式――寻找操作数的方法。

CPU可以直接将数据本身与指令一起编码作为指令代码的一部分,也可以存放在寄存器或主存储器中,这就对应立即数寻址、寄存器寻址和存储器寻址方式。又由于存储器地址有多种表示方法,于是又存在多种存储器寻址方式;8086支持的存储器寻址方式有:直接寻址、寄存器间接寻址、寄存器相对寻址、基址变址寻址、相对基址变址寻址方式。

8086CPU的机器代码(Machine Code,也称指令代码Instruction Code)一般格式:操作码占1个或2个字节,后面的各个字节指明操作数。其中,“mod reg r/m”字节表明寻找操作数的方式(即采用的寻址方式),“位移量”字节给出某些寻址方式需要的相对基地址的偏移量,“立即数”字节给出立即寻址方式需要的数值本身。操作数的各个字段有多种组合。

8086指令最多可以有两个操作数。在“mod reg r/m”字节中,reg字段表示一个采用寄存器寻址的操作数;reg占用3位,不同编码指示8个8位(w=0)或16位(w=1)通用寄存器之一。mod和r/m字段表示另一个操作数的寻址方式,分别占用2位和3位。

  • mod=00――无位移量的存储器寻址方式。但其中,当r/m=110时为直接寻址方式,此时该字节后跟16位有效地址D16。
  • mod=01――带有8位位移量的存储器寻址方式。此时该字节后跟1个字节量,表示8位位移量D8,它是一个有符号数。
  • mod=10――带有16位位移量的存储器寻址方式。此时该字节后跟2个字节(字)量,表示16位位移量D16,它也是一个有符号数。
  • mod=11――寄存器寻址方式,由r/m指定寄存器,r/m此时的编码与reg相同。


除了上述一般机器代码格式外,8086CPU还有其它机器代码格式。
读者不能理解机器代码,没有关系,不会影响程序设计。现在,只要能够理解最常用的传送指令MOV功能:
    MOV dest,src     ;dest←src  
MOV指令的功能是将源操作数src传送至目的操作数dest。

在立即数寻址方式下,指令中的操作数就直接存放在机器代码中,紧跟在操作码之后。这条指令汇编成机器代码后,操作数作为指令的一部分存放在操作码之后的主存单元中。称这种操作数为立即数imm,它可以是8位数值i8(00H ~ FFH),也可以是16位数值i16(0000H ~ FFFFH)。
立即数寻址方式常用来给寄存器赋值。

例:将16位立即数0102H送至AX寄存器
    MOV AX,0102H     ;AX←0102H
该指令机器代码为“B8 02 01”,其中B8为操作码,紧接着16位立即数0102H。注意高字节01H存放于高地址中,低字节存放于低地址单元中。

寄存器寻址方式的操作数存放在CPU的内部寄存器reg中,
它可以是8位寄存器r8:AH / AL / BH / BL / CH / CL / DH / DL;
也可以是16位寄存器r16:AX / BX / CX / DX / SI / DI / BP / SP。
另外,操作数还可以存放在4个段寄存器中seg:CS / DS / SS / ES。
寄存器寻址方式的操作数存放于CPU的某个内部寄存器中,不需要访问存储器,因而执行速度较快,是经常使用的方法。

例:将寄存器AX的内容传送给BX寄存器保存
    MOV BX,AX     ;两个操作数均为寄存器寻址:BX←AX

如何寻址主存中存储的操作数就称为存储器寻址方式,也称为主存寻址方式:

  • 主存寻址方式下,指令给出操作数的主存地址信息;
  • 8086分段管理主存储器空间,主存地址在编程时采用逻辑地址;
  • 逻辑地址由段地址和偏移地址组成;
  • 主存寻址时,段地址在默认的或用段超越前缀指定的段寄存器中;
  • 主存寻址时,偏移地址被称有效地址EA(Effective Address),需要指令指定

为了方便各种数据结构的存取,根据有效地址的提供方法不同,8086设计了多种主存寻址方式:

  1. 直接寻址方式
  2. 寄存器间接寻址方式
  3. 寄存器相对寻址方式
  4. 基址变址寻址方式
  5. 相对基址变址寻址方式

指令中直接包含了有效地址。16位有效地址紧接着操作码,存放在代码段中。默认的段地址在DS段寄存器中,但可使用段超越前缀改变。
汇编语言的语法中,一般规定用中括号表达存储单元的内容。所以为了区别于16位立即数,书写汇编指令时要将16位有效地址加上中括号。

例1:将数据段中偏移地址2000H的一个16位数据传送给AX
    MOV AX,[2000H]     ;AX←DS:[2000H],指令代码:A10020
该指令中给定了有效地址2000H,它还不是存储器的物理地址。默认情况下,有效地址要与数据段寄存器DS一起构成操作数所在存储单元的物理地址。

寄存器间接寻址方式中,有效地址存放在基址寄存器BX或变址寄存器SI、DI中。默认的段地址在DS段寄存器中,但可使用段超越前缀改变。

例:将数据段中由SI指定偏移地址的一个16位数据传送给AX
    MOV AX,[SI]     ;AX←DS:[SI]
该指令中有效地址存放于SI寄存器中,而操作数则存放在数据段主存单元中。假设SI内容设置为2000H,则该指令等同于MOV AX, [2000H]。

寄存器相对寻址方式下,有效地址是寄存器内容与有符号8位或16 位位移量之和,寄存器可以是BX、BP或SI、DI。其中采用BX、SI、DI寄存器则默认是数据段DS,采用BP 寄存器默认是堆栈段SS;当使用非默认段时,可用段超越前缀。

操作数的有效地址应该是:有效地址=BX / BP / SI / DI + 8 / 16位位移量

例:将数据段中由DI内容加上6作为偏移地址指向的一个16位数据传送给AX
    MOV AX,[DI+06H]     ;AX←DS:[DI+06H]
这条指令中使用的是DI寄存器,位移量为06H,那么操作数的有效地址EA=DI+06H,与DI寄存器约定的段是数据段是DS。

例:将堆栈段中由BP内容加上6作为偏移地址指向的一个16位数据传送给AX
    MOV AX,[BP+06H]     ;AX←SS:[BP+06H]
该指令使用的是BP寄存器,与之约定的段为堆栈段SS。

基址变址寻址方式是把一个基址寄存器(BX或BP)的内容加上变址寄存器(SI或DI)的内容构成有效地址EA。若基址寄存器使用BX,其默认段为数据段DS;若基址寄存器使用BP,其默认段为堆栈段SS。

操作数的有效地址EA为:有效地址=BX / BP + SI / DI

例:
    MOV AX,[BX+SI]        ;AX←DS:[BX+SI]
    MOV AX,[BP+DI]        ;AX←SS:[BP+DI]
    MOV AX,DS:[BP+DI]     ;AX←DS:[BP+DI]

相对基址变址寻址方式,也使用基址寄存器(BX / BP)和变址寄存器(SI / DI), 另外还在指令中指定一个8位或16位的位移量,这三者之和构成操作数的有效地址EA,与BX寄存器约定的段为数据段DS,与BP寄存器约定的段为堆栈段SS。

相对基址变址寻址方式的有效地址=BX / BP + SI / DI + 8 / 16位位移量

例:
    MOV AX,[BX+SI+06H]     ;AX←DS:[BX+SI+06H]

操作数寻址方式是汇编语言的重点和难点。请按如下思路学习:

1. 操作数可以存在什么地方?

⑴ 操作数存在于指令代码中,处理器译码时就立即获得了这个操作数,这就是立即(数)寻址方式。汇编指令中,这个立即数(操作数)以常量形式出现。

⑵ 操作数存在于处理器内部寄存器中,处理器从寄存器中获得这个操作数, 这就是寄存器寻址方式。汇编指令中,这个寄存器操作数以寄存器名形式出现。

⑶ 操作数存在于主存中,处理器从主存单元获得这个操作数,这就是存储器寻址方式。汇编指令中,这个存储器操作数以主存地址形式出现。

2. 8086/8088处理器的主存地址在程序设计时采用逻辑地址。
逻辑地址分成段地址和偏移地址两部分。

3. 存储器寻址方式表达存储器地址时,段地址在默认的或段超越前缀指令指定的段寄存器中,偏移地址被称为有效地址EA(Effective Address)。有效地址用中括号括起来。

4. 有多种获得偏移地址的方法,所以存储器寻址方式又分成多种寻址方式。

⑴ 有效地址直接给出,存在于指令代码中,就是直接寻址方式。

⑵ 有效地址存在寄存器中,就是通过寄存器的间接寻址方式。

⑶ 有效地址是两部分的和,一部分在寄存器中,另一部分直接给出(称为位移量),这就是寄存器相对寻址方式。

⑷ 有效地址是两部分的和,一部分在基址寄存器中(8086是BX和BP),另一部分在变址寄存器中(8086是SI和DI),这就是基址变址寻址方式。

⑸ 有效地址是三部分的和,第一部分在基址寄存器中(8086是BX和BP),第二部分在变址寄存器中(8086是SI和DI),第三部分直接给出(称为位移量),这就是相对基址变址寻址方式。

5. 区别各种寻址方式时,注意各自的特点。

只有一个常量,是立即(数)寻址方式;只有一个寄存器名,是寄存器寻址方式;其他则是存储器寻址方式。用中括号括起一个常量是直接寻址方式;用中括号括起一个寄存器名,是寄存器间接寻址方式;用中括号括起一个寄存器名和一个常量是寄存器相对寻址方式;用中括号括起两个寄存器名是基址变址寻址方式;用中括号括起两个寄存器名和一个常量是相对基址变址寻址方式。

6. 汇编语句中,还有其他形式出现,需要理解相应操作符才能做出正确判断。
例如,直接写出变量名实际上是直接寻址方式;变量名加减一个常量还是直接寻址方式;变量名和一个寄存器则是寄存器相对寻址方式;利用offset后跟一个变量名则是立即数寻址方式。

阅读(6281) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-06-20 10:44:16

bistu-mawenxiao,find 2k_debug_kernel,sometimes d->rf->zr(or nz),only show IP=???? NV,even [2b0,59d5] hold still(ie silence),but 99.999999%,can show ip=???? NV UP ..NC