7种寻址方式,以及有效地址计算方法。

七种寻址方式

操作数是指令或程序的主要处理对象。如果某条指令或某个程序不处理任何操作数,那么,该指令或程序不可能有数据处理功能。在CPU的指令系统中,除NOP(空操作指令)、HLT(停机指令)等少数指令之外,大量的指令在执行过程中都会涉及到操作数。所以,在指令中如何表达操作数或操作数所在位置就是正确运用汇编指令的一个重要因素。

在指令中,指定操作数或操作数存放位置的方法称为寻址方式

微机系统有七种基本的寻址方式:立即寻址方式、直接寻址方式、寄存器寻址方式、寄存器间接寻址方式、寄存器相对寻址方式、基址加变址寻址方式、相对基址加变址寻址方式等。其中,后五种寻址方式是确定内存单元有效地址的五种不同的计算方法,用它们可方便地实现对数组元素的访问。

另外,在32位微机系统中,为了扩大对存储单元的寻址能力,增加了一种新的寻址方式——32位地址的寻址方式。

为了表达方便,我们用符号“(X)”表示X的值,如:(AX)表示寄存器AX的值。

助记图:

在这里插入图片描述

1 立即寻址方式:

操作数就包含在指令中。作为指令的一部分,跟在操作码后存放在代码段。
这种操作数成为立即数。立即数可以是8位的,也可以是16位的。
例如:

指令: MOV AX,1234H
  则: AX = 1234H
2 直接寻址方式:

http://www.cnblogs.com/lilongjiang/archive/2011/06/14/2080551.html
指令所要的操作数存放在内存中,在指令中直接给出该操作数的有效地址,这种寻址方式为直接寻址方式。
在通常情况下,操作数存放在数据段DS中,所以,其物理地址将由数据段寄存器DS和指令中给出的有效地址直接形成,但如果使用段超越前缀,那么,操作数可存放在其它段。
例:假设有指令:MOV BX, [1234H],在执行时,(DS)=2000H,内存单元21234H的值为5213H。问该指令执行后,BX的值是什么?
解:根据直接寻址方式的寻址规则,把该指令的具体执行过程用下图来表示。
从图中,可看出执行该指令要分三部分:
在这里插入图片描述
由于1234H是一个直接地址,它紧跟在指令的操作码之后,随取指令而被读出;
访问数据段的段寄存器是DS,所以,用DS的值和偏移量1234H相加,得存储单元的物理地址:21234H;
取单元21234H的值5213H,并按“高高低低”的原则存入寄存器BX中。
所以,在执行该指令后,BX的值就为5213H。

3 寄存器寻址方式:

操作数在CPU内部的寄存器中,指令指定寄存器号。
对于16位操作数,寄存器可以是:AX、BX、CX、DX、SI、DI、SP和BP等。
对于8位操作数,寄存器可以是AL 、AH、BL、BH、CL、CH、DL、DH。
这种寻址方式由于操作数就在寄存器中,不需要访问存储器(比如内存)来取得操作数,因而可以取得较高的运算速度。

4 寄存器间接寻址方式:

操作数在寄存器中,操作数有效地址在SI、DI、BX、BP这四个寄存器之一中。在不使用段超越前缀的情况下,如果有效地址在SI、DI和BX中,则以DS段寄存器中的内容为段值。如果有效地址在BP中,则以SS段寄存器中的内容为段值。该寻址方式物理地址的计算方法如下:
在这里插入图片描述
寄存器间接寻址方式读取存储单元的原理如图所示:
在这里插入图片描述
例如:
MOV AX, [DI]
如果(DS) = 1000H (DI) = 2345H
则物理地址 = 1000H * 16 + 2345H = 12345H
12345H地址中的内容为:4354H
执行该指令后,(AX) = 4354H
如图所示:
在这里插入图片描述

5 寄存器相对寻址方式:

操作数在存储器中,操作数的有效地址是一个基址寄存器(BX、BP)或变址寄存器(SI、DI)的内容加上指令中给定的8位或16位位移量之和。

BX    8位    位移量
EA(有效地址) =  BP  + 
SI    16位    位移量
DI

在一般情况下,如果SI、DI、或BX中的内容作为有效地址的一部分,那么引用的段寄存器是DS;如果BP中的内容作为有效地址的一部分,那么引用的段寄存器是SS。

物理地址 = 16d × (DS) + (BX) + 8
      或(SI)或16位位移 
      或(DI)   
物理地址 = 16d × (SS) + (BP) + 8位位移量
             或16位位移量

在指令中给定的8位或16位位移量采用补码形式表示。在计算有效地址时,如位移量是8位,则被带符号扩展成16位。
例如:
MOV AX,[DI+1223H]
假设,(DS) = 5000H,(DI) = 3678H
则物理地址 = 50000 + 3678 + 1233 = 5489BH
5489BH地址中的内容:55AAH
执行该指令后AX = 55AAH
下面指令中,源操作数采用寄存器相对寻址,引用的段寄存器是SS: MOV BX,[BP-4]
下面指令中,目的操作数采用寄存器相对寻址,引用的段寄存器是ES: MOV ES:[BX+5],AL
指令:MOV AX,[SI+3]与MOV AX,3[SI]是等价的

6 基址加变址寻址方式:

操作数在寄存器中,操作数的有效地址由:
基址寄存器之一的内容与变址寄存器之一的内容相加

    BX   SI
即: EA =  +  
    BP   DI    

在一般情况下,如果BP之内容作为有效地址的一部分,则以SS之内容为段值,否则已DS为段值。

例如:
MOV AX,[BX][DI]
如:(DS)=2100H,
   (BX)=0158H,
   (DI)=10A5H
则EA=0158 + 10A5 = 11FD
物理地址=21000 + 11FD = 221FDH
221FDH地址中的内容:1234H
执行该指令后AX = 1234H

下面指令中,目的操作数采用基址加变址寻址,
引用的段寄存器是DS: MOV DS:[BP+SI],AL

下面指令中,源操作数采用基址加变址寻址,
引用的段寄存器ES: MOV AX,ES:[BX+SI]

这种寻址方式使用与数组或表格处理。用基址寄存器存放数组首地址,而用变地寄存器来定位数组中的各元素,或反之。由于两个寄存器都可改变,所以能更加灵活地访问数组或表格中的元素。
下面的两种表示方法是等价的:
MOV AX,[BX+DI]
MOV AX,[DI][BX]

7 相对基址加变址寻址方式:

操作数在存储器中,操作数的有效地址由于基址寄存器之一的内容与变址寄存器之一的内容及指令中给定的8位或16位位移量相加得到。

    BX    SI    8位
即: EA =     +     +      位移量
    BP    DI    16位

在一般情况下,如果BP中的内容作为有效地址的一部分,则以SS段寄存器中的内容为段值,否则以DS段寄存器中的内容为段值。
在指令中给定的8位或16位位移量采用补码形式示。
在计算有效地址时,如果位移量是8位,那么被带符号扩展成16位。
当所得的有效地址操作FFFFH时,就取其64K的模

例如:
MOV AX,[BX+DI-2]
假设,(DS) = 5000H, (BX) = 1223H, DI = 54H, (51275) = 54H, (51276) = 76H
物理地址= 50000 + 1223 + 0054 + FFFE(-2 各位取反末位加一) = 51275H
执行该指令后 (AX) = 7654H

相对基址加变址这种寻址方式的表示方法多种多样,以下四种方法均是等价的:
MOV AX,[BX+DI+1234H], MOV AX,1234H[BX][DI]
MOV AX 1234H[BX+DI], MOV AX,1234H[DI][BX]

————————————————
版权声明:本文为CSDN博主「bytxl」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bytxl/article/details/48462987

  • 45
    点赞
  • 321
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
根据您的回复,我理解您是想了解如何在Pwm Testbench中进行寻址模拟(simulation)。 在Testbench中,我们通常需要对PWM控制器的寄存器进行读写操作,以配置其工作状态或读取状态信息。在进行仿真之前,我们需要定义PWM控制器的输入输出信号,并实例化PWM控制器模块。同时,我们还需要定义寄存器映射,并初始化其值。 在进行仿真时,我们可以通过调用pwm_write_reg任务来写入PWM控制器的寄存器值,通过pwm_read_reg任务来读取PWM控制器的寄存器值。在写入和读取寄存器值时,需要指定寄存器地址(addr)和数据值(data)。 下面是一个简单的PWM Testbench的寻址模拟示例: ```verilog `timescale 1ns/1ns module pwm_controller_tb; //定义PWM控制器的输入输出信号 reg clk; reg rst; reg [7:0] duty_cycle; wire pwm_out; //实例化PWM控制器 pwm_controller dut ( .clk(clk), .rst(rst), .duty_cycle(duty_cycle), .pwm_out(pwm_out) ); //定义寄存器映射 reg [31:0] pwm_reg [0:255]; //初始化寄存器映射 initial begin for (int i = 0; i < 256; i++) begin pwm_reg[i] = 32'h00000000; end end //读写PWM控制器的寄存器 task pwm_write_reg; input [7:0] addr; input [31:0] data; begin pwm_reg[addr] = data; end endtask task [31:0] pwm_read_reg; input [7:0] addr; begin pwm_read_reg = pwm_reg[addr]; end endtask //模拟对PWM控制器的访问 initial begin //写入寄存器 pwm_write_reg(8'h01, 32'h0000FFFF); pwm_write_reg(8'h02, 32'h000000FF); //读取寄存器 $display("PWM_CTRL: %h", pwm_read_reg(8'h01)); $display("PWM_DUTY: %h", pwm_read_reg(8'h02)); //模拟PWM信号 clk = 1'b0; rst = 1'b1; #10 rst = 1'b0; #10 clk = 1'b1; #10 clk = 1'b0; #10; for (int i = 0; i < 256; i++) begin duty_cycle = i; #10; end end endmodule ``` 在这个PWM Testbench的寻址模拟中,我们首先使用pwm_write_reg任务写入了PWM_CTRL和PWM_DUTY这两个寄存器的值,然后通过pwm_read_reg任务读取了这两个寄存器的值并将其打印出来。最后通过对duty_cycle的赋值来模拟了PWM信号的变化。在仿真过程中,模拟器会根据寄存器映射中的值来模拟PWM控制器的行为。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值