第四章 操作数的寻址方式

目录

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张图片

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

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

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

4.1 立即寻址方式n

4.1.1 使用格式及功能

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

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

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

格式:n

第四章 操作数的寻址方式_第3张图片

第四章 操作数的寻址方式_第4张图片

4.1.2 例子

第四章 操作数的寻址方式_第5张图片

4.2 寄存器寻址方式R

4.2.1 使用格式及功能

格式:R

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

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

4.2.2 例子

第四章 操作数的寻址方式_第6张图片

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

第四章 操作数的寻址方式_第7张图片

第四章 操作数的寻址方式_第8张图片

4.3 直接寻址方式[n]

4.3.1 使用格式及功能

  • 操作数在内存中

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

第四章 操作数的寻址方式_第9张图片

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

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

第四章 操作数的寻址方式_第10张图片

4.3.2 读操作

第四章 操作数的寻址方式_第11张图片

4.3.3 写操作

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

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

第四章 操作数的寻址方式_第12张图片

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

第四章 操作数的寻址方式_第13张图片

例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] 不符合规定❌

第四章 操作数的寻址方式_第14张图片

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

第四章 操作数的寻址方式_第15张图片

第四章 操作数的寻址方式_第16张图片

4.4.2 例子

例1: MOV AX,[BX]

第四章 操作数的寻址方式_第17张图片

例2: MOV SS:[DI],AX

第四章 操作数的寻址方式_第18张图片

  • 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个数据,求他们的和。

第四章 操作数的寻址方式_第19张图片

算法分析:

  • 循环次数

  • 数据位置 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

第四章 操作数的寻址方式_第20张图片

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

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

4.5.1 使用格式及功能

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

格式:[R+n]

第四章 操作数的寻址方式_第21张图片

4.5.2 例子

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

第四章 操作数的寻址方式_第22张图片

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

第四章 操作数的寻址方式_第23张图片

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

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

第四章 操作数的寻址方式_第24张图片

第四章 操作数的寻址方式_第25张图片

第四章 操作数的寻址方式_第26张图片

 段地址(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]

第四章 操作数的寻址方式_第27张图片

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

第四章 操作数的寻址方式_第28张图片

例:用变址寻址方式写一段程序,求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语言放在变量里面,汇编放在寄存器里面。

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

第四章 操作数的寻址方式_第29张图片

 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]

第四章 操作数的寻址方式_第30张图片

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

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

    第四章 操作数的寻址方式_第31张图片

第四章 操作数的寻址方式_第32张图片

第四章 操作数的寻址方式_第33张图片

第四章 操作数的寻址方式_第34张图片

第四章 操作数的寻址方式_第35张图片

4.7.2 例

第四章 操作数的寻址方式_第36张图片

4.8 小结

第四章 操作数的寻址方式_第37张图片

你可能感兴趣的:(汇编,java,开发语言)