第四章 操作数的寻址方式

本文深入探讨了计算机指令中寻找操作数的多种寻址方式,包括立即寻址、寄存器寻址、直接寻址、寄存器间接寻址、寄存器相对寻址、基址变址寻址和相对基址变址。通过实例解析了各种寻址方式的使用格式、功能和应用场景,展示了如何通过不同寻址方式在CPU、内存和I/O设备间处理数据。
摘要由CSDN通过智能技术生成

目录

4.1 立即寻址方式n

4.1.1 使用格式及功能

4.1.2 例子

4.2 寄存器寻址方式R

4.2.1 使用格式及功能

4.2.2 例子

4.3 直接寻址方式[n]

4.3.1 使用格式及功能

4.3.2 读操作

4.3.3 写操作

4.3.4 符号地址

4.3.5 段前缀

4.3.6 例子

4.4 寄存器间接寻址方式[R]

4.4.1 使用格式及功能

4.4.2 例子

4.5 寄存器相对寻址方式[R+n]

4.5.1 使用格式及功能

4.5.2 例子

4.6 基址变址寻址方式V[R×F]

4.6.1 使用格式及功能

4.6.2 例子

4.7 相对基址变址寻址方式[BR+IR×F+V]

4.7.1 使用格式及功能

4.7.2 例

4.8 小结


寻址方式就是指令中寻找操作数的方式。对于每一条指令,我们需要关注指令执行什么操作?操作数存放在的位置?。那机器指令处理的数据在什么地方?

操作数的存放地址

  1. CPU的寄存器

  2. 内存

  3. I/O设备接口

操作数在主存时:关注段址/段选择符、段内偏移——物理地址

操作数的类型:字节/字/双字

数据处理大致可分为3类:读取、写入、运算。在机器指令这一层来讲,并不关心数据的值是多少,而关心指令执行前一刻,它将要处理的数据所在的位置。指令在执行前,所要处理的数据可以在3个地方:CPU内部、内存、端口

  • 指令:操作码操作数组成。操作数字段可以有一个、两个或三个,通常称为一地址、二地址或三地址指令。

  • 二地址指令中两个操作数:源操作数和目的操作数。

  • 格式: [标号:] 指令助记符 [操作数] [;注释]

双操作数指令的两点提示:

(1) 双操作数指令的两个操作数,长度须匹配。

(2) 双操作数指令的两个操作数中,不能两个操作数同为内存单元。

4.1 立即寻址方式n

4.1.1 使用格式及功能

  • 操作数直接放在指令中,在指令的操作码后;

  • 操作数是指令的一部分,位于代码段中;

  • 指令中的操作数是8位、16位或32位二进制数。

格式:n

4.1.2 例子

4.2 寄存器寻址方式R

4.2.1 使用格式及功能

格式:R

功能:操作数存放在寄存器。指令中给出寄存器名。

说明:除个别指令外,R可为任意寄存器

4.2.2 例子

  • 源操作数和目的操作数类型需要一致。

4.3 直接寻址方式[n]

4.3.1 使用格式及功能

  • 操作数在内存中

  • 操作数的有效地址EA就在指令中,紧跟操作码后面。机器默认段地址在DS中。

操作数所在的:由段寄存器名指示,或者是变量所在的段

操作数的类型:若有变量,则是定义变量的类型

4.3.2 读操作

4.3.3 写操作

如果要实现CPU写内存操作,只要把MOV指令的目的操作数变为存储单元,源操作数为CPU的寄存器即可。

  • 例4-5 MOV DS: [4000H], AX

4.3.4 符号地址

直接寻址方式除了用数值作为有效地址之外,还可以用符号地址的形式。为存储单元定义一个名字,该名字就是符号地址。如果把存储单元看成变量,该名字也是变量名。

4.3.5 段前缀

在与内存有关的寻址方式中,操作数的段地址默认为数据段,80X86规定除了数据段之外,数据还可以存放在其他三种段中。如果操作数在其他段中存放,称为段超越,需要在指令中用段超越前缀指出,即用操作数前加上段寄存器名和冒号表示。

 mov ax, ds:[bx]
 mov ax, cs:[bx]
 mov ax, ss:[bx]
 mov ax, es:[bx]
 mov ax, ss:[0]
 mov ax, cs:[0]

4.3.6 例子

例1. VALUE EQU 1000H

例2:计算2^12 

assume cs:code 
 ​
 code segment 
     mov ax, 2   
     mov cx, 11 ;循环次数
 s:  add ax, ax 
     loop s     ;在汇编语言中,标号代表一个地址,标号s实际上标识了一个地址,
                ;这个地址处有一条指令:add ax,ax。
                ;执行loop s时,首先要将(cx)减1,然后若(cx)不为0,则向前
                ;转至s处执行add ax,ax。所以,可以利用cx来控制add ax,ax的执行次数。
     mov ax,4c00h 
     int 21h 
 code ends 
 end

例3:将内存ffff:0 ~ ffff:b单元中的数据复制到0:200 ~ 0:20b单元中。 

assume cs:code
 ​
 code segment
     mmov ax,0ffffh
     mov ds,ax       ;(ds)=0ffffh
     mov ax,0020h
     mov es,ax       ;(es)=0020h  0:200→0020:0
     mov bx,0        ;(bx)=0,此时ds:bx指向ffff:0,es:bx指向0020:0
     
     mov cx,12   ;循环12次
 s:  mov dl,[bx] ;(d1)=((ds)* 16+(bx)),将ffff:bx中的字节数据送入dl 
     mov es:[bx],dl ;((es)*16+(bx))=(d1),将dl中的数据送入0020:bx 
     inc bx  ;(bx)=(bx)+1
     loop s 
     
     mov ax,4c00h 
     int 21h 
 code ends 
 end

4.4 寄存器间接寻址方式[R]

4.4.1 使用格式及功能

格式[R]

功能:操作数在内存中,操作数的偏移地址在寄存器R中,即(R)位操作数的偏移地址。

操作数的有效地址在寄存器中,只允许使用BX、BP、SI和DI寄存器。

eg:MOV AX,[CX] 不符合规定❌

  • 寄存器间接寻址方式的寻址过程:

4.4.2 例子

例1: MOV AX,[BX]

例2: MOV SS:[DI],AX

  • MOV AX,[BX] ;默认DS寄存器作段地址

  • MOV DX,[BP] ;默认SS寄存器作段地址

  • MOV ES:[DI],AX ;指定ES寄存器作段地址

例3:比较

  • MOV AX,BX

  • MOV AX,[BX]

例4:设BUF DB 10,20,30,40,50即以BUF为首址的字节区中存有5个数据,求他们的和。

算法分析:

  • 循环次数

  • 数据位置 BX (0005)([BX])

  • 单元中的内容无规律,但单元的地址有规律

 SEG1 SEGMENT USE16 STACK
     DB 200 DUP(0)
 SEG1 ENDS
 ​
 SEG2 SEGMENT USE16
     BUF DB 10,20,30,40,50
     RES DB  ?
 SEG2   ENDS
 ​
 SEG3    SEGMENT  USE16
     ASSUME  CS:SEG3, 
             DS:SEG2,SS:SEG1
 START: MOV AX,SEG2
         MOV DS,AX
         MOV CX,0      ; 计数
         MOV AH,0      ; 和
         MOV BX,OFFSET BUF   ;取buf的偏移地址
     LP: CMP CX,5
         JGE EXIT
         ADD AH,[BX]    
         INC BX
         INC CX 
         JMP LP
     EXIT:MOV RES,AH
     MOV AX,4C00H
     INT 21H
 SEG3  ENDS
 END  START

Question:ADD AH, [BX]可否换成 ADD AH, BX?不可以

C语言:

 SEG1 SEGMENT USE16 STACK
     DB 200 DUP(0)
 SEG1 ENDS
 ​
 SEG2 SEGMENT USE16
     BUF DB 10,20,30,40,50
     RES DB  ?
 SEG2   ENDS
 ​
 SEG3    SEGMENT  USE16
     ASSUME  CS:SEG3, 
             DS:SEG2,SS:SEG1
 START: MOV AX,SEG2
         MOV DS,AX
         MOV CX,0      ; 计数
         MOV AH,0      ; 和
         MOV BX,OFFSET BUF   ;取buf的偏移地址
     LP: CMP CX,5
         JGE EXIT
         ADD AH,[BX]    
         INC BX
         INC CX 
         JMP LP
     EXIT:MOV RES,AH
     MOV AX,4C00H
     INT 21H
 SEG3  ENDS
 END  START

p与BX对应:ADD EAX,[BX] ADD BX,4

4.5 寄存器相对寻址方式[R+n]

4.5.1 使用格式及功能

操作数的有效地址是一个寄存器位移量之和。

格式:[R+n]

4.5.2 例子

例: MOV AX, TOP[SI],指令TOP为符号地址,即位移量。

例: MOV AX,[BX+2623H]或写成MOV AX,[BX].2623H

4.6 基址变址寻址方式V[R×F]

4.6.1 使用格式及功能

格式:[R×F+V] 或 [R×F]+V 或 V[R×F]

功能:R中的内容×F+V,为操作数的偏移地址

  • 操作数的有效地址是一个基址寄存器和一个变址寄存器的内容之和。

  • 基址寄存器BX和BP,变址寄存器SI和DI

  • F可以为1,2,4,8(比例因子),当R为16位寄存器时,F只能为1

  • 默认段寄存器搭配和寄存器间接寻址方式一样。

 段地址(SA)和偏移地址(EA)
 ;指令要处理的数据在内存中,在汇编指令中可用[X]的格式给出EA,SA在某个段寄存器中。
 mov ax, [0]
 mov ax, [di]
 mov ax, [bx+8]
 mov ax, [bx+si]
 mov ax, [bx+si+8]   ;以上段地址默认在ds中
 ​
 mov ax, [bp]
 mov ax, [bp+8]
 mov ax, [bp+si]
 mov ax, [bp+si+8]   ;以上段地址默认在ss中
 ​
 mov ax, ds:[bp]
 mov ax, es:[bx]
 mov ax, ss:[bx+si]
 mov ax, cs:[bx+si+8] ;显式给出存放段地址的寄存器

4.6.2 例子

例: MOV AX, [BX+DI]

例:MOV AL, [EBX*2]+5

例:用变址寻址方式写一段程序,求BUF中数据的和

STACK SEGMENT USE16 STACK
     DB 200 DUP(0)
 STACK ENDS
 ​
 SEG1 SEGMENT USE16D
     BUF DD 10,20,30,40,50
     RES DD  ?
 SEG1   ENDS
 ​
 CODE SEGMENT  USE16
     ASSUME  CS:CODE
             DS:SEG1,SS:STACK
 START: MOV AX,SEG1
         MOV DS,AX
         MOV EBX,0      ; 计数
         MOV EAX,0      ; 和
     LP: CMP EBX,5
         ADD EAX,BUF[EBX*4]  
         INC EBX 
         JMP LP
     EXIT:MOV RES,EAX
     MOV AX,4C00H
     INT 21H 
 CODE ENDS
     END  START
int buf[5]={10,20,30,40,50};
 int i;
 int res = 0;
 p = buf;
 for{i=0;i<5;i++}{
     res+ = buf[i];
 }

思考:(EBX) 中的值就是变量i的值,为何C语言中的访问方是 buf[i],而汇编语言中是 buf[EBX*4] ?

C语言放在变量里面,汇编放在寄存器里面。

  • 比较变址寻址和寄存器间接寻址有何异同

 1.遍历EBX第几个元素
 2.EBX里面的值就是偏移地址,不知道BUF放在什么位置,类似于指针用法。

例:

设 BUF1 DB 10,20,25,37,50 即以BUF1 为首地址的字节区存放有5个数据,将他们拷贝到以BUF2为首址的字节去。与数组类比:A[0],A[1],A[2],......B[0],B[1],B2[2]

for (i=0;i<5;i++)  
     BUF2[i] = BUF1[i];
         MOV BX,0    ;BX:第几个元素
 MAINP:  CMP  BX,5
         JGE EXIT
         MOV AL,BUF1[BX]
         MOV BUF2[BX], AL    ;两个立即数不能直接传送
         INC BX
         JMP MAINP
 EXIT:

用寄存器间接寻址程序段

     MOV SI,OFFSET BUF1  ;取地址
     MOV DI,OFFSET BUF2  
     MOV CX,5
 MAINP:  MOV AL,[SI]
         MOV [DI],AL
         INC SI
         INC DI
         DEC CX
         JNZ MAINP
 EXIT:

设 BUF1 DB 10,20,25,37,50 即以BUF1 为首地址的双字去存放有5个数据,将他们拷贝到以BUF2为首址的字节区。

 for(i=0;i<5;i++)
     BUF2[i] = BUF1[i];
         MOV BX,0
 MAINP:  CMP  BX,5
         JGE EXIT
         MOV AL,BUF1[BX*4]
         MOV BUF2[BX*4], AL
         INC BX
         JMP MAINP
 EXIT:
 MOV SI,OFFSET BUF1
     MOV DI,OFFSET BUF2
     MOV CX,5
 MAINP:MOV AL,[SI]
         MOV [DI],AL
         INC SI
         INC DI
         DEC CX
         JNZ MAINP

4.7 相对基址变址寻址方式[BR+IR×F+V]

4.7.1 使用格式及功能

格式:[BR+IR×F+V] 或 V[BR] [IR×F] 或V[IR×F] [BR] 或V[BR+IR×F]

功能:操作数的偏移 = 变址寄存器IR中的内容×比例因子F+位移量V+基址寄存器BR中的内容

$$
EA = (IR)*F+V+(BR)
$$

  • 操作数的有效地址是一个基址寄存器和一个变址寄存器以及一个位移量之和。

  • 基址寄存器BX和BP,变址寄存器SI和DI

  • 默认段寄存器搭配和寄存器间接寻址方式一样

4.7.2 例

4.8 小结

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值